Skip to content
Snippets Groups Projects
Commit 7c7920ba authored by François Grand's avatar François Grand
Browse files

feat: parameterised sections: add check button to apply 1:1 aspect ratio to graph

refs #497
parent cfd9c237
No related branches found
No related tags found
1 merge request!171Resolve "Section paramétrée - profil de section: option axes orthonormés"
<canvas #canvas [attr.width]="width" [attr.height]="height">
</canvas>
<div fxLayout="column" fxLayoutAlign="center center">
<canvas #canvas [attr.width]="width" [attr.height]="height">
</canvas>
<mat-checkbox [ngModel]="useRealAspectRatio" (ngModelChange)="setUseRealAspectRatio($event)">
{{ uitextUseRealRatio }}
</mat-checkbox>
</div>
\ No newline at end of file
import { Component, ViewChild, Input, OnChanges, AfterViewInit, ElementRef } from "@angular/core";
import { I18nService } from "app/services/internationalisation.service";
import {
acSection, cSnTrapez, ParamsSectionTrapez, cSnRectang, ParamsSectionRectang, cSnCirc,
......@@ -40,19 +41,44 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
private _result: Result;
/**
* paramètre de taille du canvas en entrée (pixels)
*/
private _size: number;
/**
* taille horizontale résultante, suivant le flag de respect de l'échelle (pixels)
*/
private _sizeX: number;
/**
* taille verticale résultante, suivant le flag de respect de l'échelle (pixels)
*/
private _sizeY: number;
/**
* taille horizontale de la section (m)
*/
private _sectionWidth: number;
/**
* taille verticale de la section (m)
*/
private _sectionHeight: number;
// tirants
private _levels: Object[] = [];
constructor(private intlService: I18nService) {
super();
}
public get width(): number {
// return this._calcCanvas.nativeElement.width;
return this._size;
return this._sizeX;
}
public get height(): number {
// return this._calcCanvas.nativeElement.height;
return this._size;
return this._sizeY;
}
private _context2d: CanvasRenderingContext2D;
......@@ -63,6 +89,7 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
@Input()
public set section(s: acSection) {
this._section = s;
this.computeSectionWidth();
}
@Input()
......@@ -75,6 +102,9 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
this._size = s;
}
// respect du rapport abscisses/ordonnées
public useRealAspectRatio: boolean = false;
// redessine le canvas chaque fois qu'une entrée change
public ngOnChanges() {
setTimeout(() => {
......@@ -92,7 +122,30 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
this.clear();
}
public addLevel(val: number, label: string, rgb: {}) {
/**
* calcul des tailles horizontale et verticale du canvas (pixels)
*/
private updateCanvasSize() {
if (this.useRealAspectRatio) {
if (this._sectionWidth > this._sectionHeight) {
this._sizeX = this._size;
this._sizeY = this._size * this._sectionHeight / this._sectionWidth;
}
else {
this._sizeX = this._size * this._sectionHeight / this._sectionWidth;
this._sizeY = this._size;
}
} else {
this._sizeX = this._sizeY = this._size;
}
}
public setUseRealAspectRatio(b: boolean) {
this.useRealAspectRatio = b;
this.draw();
}
private addLevel(val: number, label: string, rgb: {}) {
this._levels.push({ val, label, rgb });
}
......@@ -111,6 +164,26 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
return false;
}
/**
* calcul des tailles horizontale et verticale de la section (m)
*/
private computeSectionWidth() {
if (this._section instanceof cSnTrapez) {
this.computeSectionWidthTrapez();
}
else if (this._section instanceof cSnRectang) {
this.computeSectionWidthRect();
}
else if (this._section instanceof cSnCirc) {
this.computeSectionWidthCirc();
}
else if (this._section instanceof cSnPuiss) {
this.computeSectionWidthPara();
}
else
throw new Error("SectionCanvasComponent.computeSectionWidth() : type de section non pris en charge");
}
public draw() {
// console.log(">> redrawing at size", this._size);
if (this._context2d && this._section) {
......@@ -136,10 +209,13 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
const valY = this._result.sourceNub.getParameter("Y").singleValue;
this.addLevel(valY, "Y = " + this.formattedValue(valY), SectionCanvasComponent.labelColors["Y"]);
this.sortLevels();
this.drawFrame();
const maxWidth = this.drawSection();
this.drawLevels(maxWidth);
this.computeSectionHeight();
this.updateCanvasSize();
setTimeout(() => { // à cause du changement de taille du canvas dans updateCanvasSize()
this.drawFrame();
this.drawSection();
this.drawLevels();
}, 10);
}
}
......@@ -157,24 +233,35 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
this.drawSectionLine(xmax, yb, xmax, maxHeight);
}
private drawSectionTrapez(): number {
private computeSectionHeight() {
this.sortLevels();
// hauteur totale de la section
this._sectionHeight = this.getMaxLevel() * 1.1;
}
private computeSectionWidthTrapez() {
const sect: cSnTrapez = <cSnTrapez>this._section;
const prms: ParamsSectionTrapez = <ParamsSectionTrapez>sect.prms;
// cote de berge
const yb: number = prms.YB.v;
// largeur de la partie pentue
const lp: number = prms.Fruit.v * prms.YB.v;
// largeur totale de la section
const maxWidth: number = lp * 2 + prms.LargeurFond.v;
this._sectionWidth = lp * 2 + prms.LargeurFond.v;
}
// hauteur totale de la section
let maxHeight: number = this.getMaxLevel();
maxHeight *= 1.1;
private drawSectionTrapez() {
const sect: cSnTrapez = <cSnTrapez>this._section;
const prms: ParamsSectionTrapez = <ParamsSectionTrapez>sect.prms;
this.computeScale(maxWidth, maxHeight);
// cote de berge
const yb: number = prms.YB.v;
// largeur de la partie pentue
const lp: number = prms.Fruit.v * prms.YB.v;
this.computeScale();
// dessin de la section
......@@ -182,13 +269,19 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
this.setLineWidth(5);
this.drawSectionLine(0, yb, lp, 0);
this.drawSectionLine(lp, 0, lp + prms.LargeurFond.v, 0);
this.drawSectionLine(lp + prms.LargeurFond.v, 0, maxWidth, yb);
this.drawSectionLine(lp + prms.LargeurFond.v, 0, this._sectionWidth, yb);
// pointillés du haut
this.drawTopDashLines(0, maxWidth, yb, maxHeight);
this.drawTopDashLines(0, this._sectionWidth, yb, this._sectionHeight);
}
private computeSectionWidthRect() {
const sect: cSnRectang = <cSnRectang>this._section;
const prms: ParamsSectionRectang = <ParamsSectionRectang>sect.prms;
return maxWidth;
// largeur totale de la section
this._sectionWidth = prms.LargeurBerge.v;
}
private drawSectionRect() {
......@@ -198,14 +291,7 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
// cote de berge
const yb: number = prms.YB.v;
// largeur totale de la section
const maxWidth: number = prms.LargeurBerge.v;
// hauteur totale de la section
let maxHeight: number = this.getMaxLevel();
maxHeight *= 1.1;
this.computeScale(maxWidth, maxHeight);
this.computeScale();
// dessin de la section
......@@ -213,13 +299,32 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
this.setLineWidth(5);
this.drawSectionLine(0, yb, 0, 0);
this.drawSectionLine(0, 0, prms.LargeurBerge.v, 0);
this.drawSectionLine(prms.LargeurBerge.v, 0, maxWidth, yb);
this.drawSectionLine(prms.LargeurBerge.v, 0, this._sectionWidth, yb);
// pointillés du haut
this.drawTopDashLines(0, maxWidth, yb, maxHeight);
this.drawTopDashLines(0, this._sectionWidth, yb, this._sectionHeight);
}
private computeSectionWidthCirc() {
const sect: cSnCirc = <cSnCirc>this._section;
const prms: ParamsSectionCirc = <ParamsSectionCirc>sect.prms;
// cote de berge
const yb: number = prms.YB.v;
// diamètre, rayon
const D: number = prms.D.v;
const r: number = D / 2;
// largeur au miroir
const B: Result = sect.CalcSection("B", yb);
if (!B.ok) {
throw B;
}
return maxWidth;
// largeur totale de la section
this._sectionWidth = yb < r ? B.vCalc : D;
}
private drawSectionCirc() {
......@@ -240,21 +345,14 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
throw B;
}
// largeur totale de la section
const maxWidth: number = yb < r ? B.vCalc : D;
// hauteur totale de la section
let maxHeight: number = this.getMaxLevel();
maxHeight *= 1.1;
this.computeScale(maxWidth, maxHeight);
this.computeScale();
// dessin de la section
this.setStrokeColor(0, 0, 0);
this.setLineWidth(5);
const wx: number = maxWidth / 2;
const wx: number = this._sectionWidth / 2;
const alpha: Result = sect.CalcSection("Alpha", yb);
if (!alpha.ok) {
throw alpha;
......@@ -267,15 +365,24 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
// pointillés du haut
const w: number = yb > r ? (D - B.vCalc) / 2 : 0;
this.drawTopDashLines(w, maxWidth - w, yb, maxHeight);
return maxWidth;
this.drawTopDashLines(w, this._sectionWidth - w, yb, this._sectionHeight);
} catch (e) {
const res: Result = e as Result;
this.drawText("error : " + res.log.toString(), 0, 0);
}
}
private computeSectionWidthPara() {
const sect: cSnPuiss = <cSnPuiss>this._section;
const prms: ParamsSectionPuiss = <ParamsSectionPuiss>sect.prms;
// largeur au miroir
const B: number = prms.LargeurBerge.v;
// largeur totale de la section
this._sectionWidth = B;
}
private drawSectionPara() {
const sect: cSnPuiss = <cSnPuiss>this._section;
const prms: ParamsSectionPuiss = <ParamsSectionPuiss>sect.prms;
......@@ -286,14 +393,7 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
// largeur au miroir
const B: number = prms.LargeurBerge.v;
// largeur totale de la section
const maxWidth: number = B;
// hauteur totale de la section
let maxHeight: number = this.getMaxLevel();
maxHeight *= 1.1;
this.computeScale(maxWidth, maxHeight);
this.computeScale();
// contour de la section
......@@ -312,9 +412,7 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
this._context2d.stroke();
// pointillés du haut
this.drawTopDashLines(0, maxWidth, yb, maxHeight);
return maxWidth;
this.drawTopDashLines(0, this._sectionWidth, yb, this._sectionHeight);
}
private drawSectionEllipse(x: number, y: number, rX: number, rY: number, rot: number, start: number, end: number) {
......@@ -333,25 +431,26 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
* dessin de la section
* @returns largeur de la section (en m)
*/
private drawSection(): number {
private drawSection() {
if (this._section instanceof cSnTrapez) {
return this.drawSectionTrapez();
this.drawSectionTrapez();
}
if (this._section instanceof cSnRectang) {
return this.drawSectionRect();
else if (this._section instanceof cSnRectang) {
this.drawSectionRect();
}
if (this._section instanceof cSnCirc) {
return this.drawSectionCirc();
else if (this._section instanceof cSnCirc) {
this.drawSectionCirc();
}
if (this._section instanceof cSnPuiss) {
return this.drawSectionPara();
else if (this._section instanceof cSnPuiss) {
this.drawSectionPara();
}
throw new Error("SectionCanvasComponent.drawSection() : type de section non pris en charge");
else
throw new Error("SectionCanvasComponent.drawSection() : type de section non pris en charge");
}
private computeScale(maxWidth: number, maxHeight: number) {
this._scaleX = (this._size - 2 * this._textMargin) / maxWidth;
this._scaleY = (this._size - this._bottomMargin) / maxHeight;
private computeScale() {
this._scaleX = (this._sizeX - 2 * this._textMargin) / this._sectionWidth;
this._scaleY = (this._sizeY - this._bottomMargin) / this._sectionHeight;
}
/**
......@@ -365,7 +464,7 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
* convertit une ordonnée en m en pixels
*/
private Ym2pix(y: number) {
return this._size - this._bottomMargin - y * this._scaleY;
return this._sizeY - this._bottomMargin - y * this._scaleY;
}
private sortLevels() {
......@@ -380,7 +479,7 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
});
}
private drawLevels(maxWidth: number) {
private drawLevels() {
let left = true;
this.resetLineDash();
......@@ -390,13 +489,13 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
const y = l["val"];
const col = l["rgb"];
this.setStrokeColor(col["r"], col["g"], col["b"]);
this.drawSectionLine(0, y, maxWidth, y);
this.drawSectionLine(0, y, this._sectionWidth, y);
this.setFillColor(col["r"], col["g"], col["b"]);
if (left) {
this.drawText(l["label"], -0.1, y, "right");
} else {
this.drawText(l["label"], maxWidth + 0.1, y, "left");
this.drawText(l["label"], this._sectionWidth + 0.1, y, "left");
}
left = !left;
}
......@@ -404,15 +503,14 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
// contour du canvas
private drawFrame() {
this.clear();
this.resetLineDash();
this.setStrokeColor(128, 128, 128);
this.drawRect(0, 0, this.width, this.height);
this.drawRect(0, 0, this._sizeX, this._sizeY);
}
public clear() {
if (this._context2d) {
this._context2d.clearRect(0, 0, this.width, this.height);
this._context2d.clearRect(0, 0, this._sizeX, this._sizeY);
}
}
......@@ -475,4 +573,8 @@ export class SectionCanvasComponent extends ResultsComponentDirective implements
this._context2d.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle);
this._context2d.stroke();
}
public get uitextUseRealRatio(): string {
return this.intlService.localizeText("INFO_SECTIONPARAMETREE_REAL_RATIO");
}
}
......@@ -584,6 +584,7 @@
"INFO_SECTIONPARAMETREE_DESCRIPTION": "open-channel canal rectangular circular trapezoidal depth head normal critical conjugate corresponding subcritical supercritical Froude",
"INFO_SECTIONPARAMETREE_TITRE_COURT": "Param. section",
"INFO_SECTIONPARAMETREE_TITRE": "Parametric section",
"INFO_SECTIONPARAMETREE_REAL_RATIO": "Apply 1:1 scale",
"INFO_SELECT_MULTIPLE_AND_OTHER": "other",
"INFO_SELECT_MULTIPLE_AND_OTHERS": "others",
"INFO_SETUP_ENABLE_HOTKEYS": "Enable keyboard shortcuts",
......
......@@ -585,6 +585,7 @@
"INFO_SECTIONPARAMETREE_DESCRIPTION": "hydraulique à surface libre canal chenal bief rectangulaire circulaire puissance trapézoïdale périmètre charge mouillée rugosité hauteur charge critique normal conjuguée correspondante fluvial torrentiel Froude",
"INFO_SECTIONPARAMETREE_TITRE_COURT": "Sec. param.",
"INFO_SECTIONPARAMETREE_TITRE": "Section paramétrée",
"INFO_SECTIONPARAMETREE_REAL_RATIO": "Respecter l'échelle",
"INFO_SELECT_MULTIPLE_AND_OTHER": "autre",
"INFO_SELECT_MULTIPLE_AND_OTHERS": "autres",
"INFO_SETUP_ENABLE_HOTKEYS": "Activer les raccourcis clavier",
......
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