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