Skip to content

Instantly share code, notes, and snippets.

@emielvangoor
Created November 30, 2021 06:56
Show Gist options
  • Save emielvangoor/7299286a6dd53b7f1b412243630e2d95 to your computer and use it in GitHub Desktop.
Save emielvangoor/7299286a6dd53b7f1b412243630e2d95 to your computer and use it in GitHub Desktop.
MTOPS MTS Gann Square
import MtopsChart from '../chart';
import { degreesToRadians } from '../lib/math';
import { Forecasting } from '../tool/turning-point-tool/forecast';
export default class GannSquare {
private _path: Path2D = new Path2D();
public static levelsRatios: { [key: number]: number } = {
1: 2.5,
2: 1.25,
3: 0.625,
};
static draw(
chart: MtopsChart,
forecasting: Forecasting,
x: number,
y: number,
size: number
): Path2D {
const shape = new GannSquare(chart, forecasting, x, y, size);
return shape.path;
}
private constructor(
private chart: MtopsChart,
private forecasting: Forecasting,
private x: number,
private y: number,
private size: number,
private levels = [0, 1, 2, 4],
private arcs = [1, 1.413, 2, 3, 4, 5]
) {
this.drawLevels(this._path);
this.drawArcs(this._path);
this.drawFans(this._path);
}
get path(): Path2D {
return this._path;
}
get sectionSize(): number {
return this.size / 5;
}
private drawFans(parent: Path2D): void {
const path = new Path2D();
path.moveTo(this.x, this.y);
[14, 26.55, 45, 63.55, 76.1].forEach((angle) => {
let r;
if (this.forecasting == Forecasting.Long) {
r = degreesToRadians(270 + angle);
} else {
r = degreesToRadians(angle);
}
let length;
if (
(this.forecasting === Forecasting.Long && angle > 45) ||
(this.forecasting === Forecasting.Short && angle < 45)
) {
length = Math.abs(this.size / Math.cos(r));
} else {
length = Math.abs(this.size / Math.sin(r));
}
const x2 = this.x + Math.cos(r) * length;
const y2 = this.y + Math.sin(r) * length;
path.moveTo(this.x, this.y);
path.lineTo(x2, y2);
});
parent.addPath(path);
}
private drawArcs(parent: Path2D): void {
this.arcs.forEach((arc) => {
const arcPath = new Path2D();
const size = this.sectionSize * arc;
if (this.forecasting == Forecasting.Long) {
arcPath.arc(this.x, this.y, size, 1.5 * Math.PI, 0);
} else {
arcPath.arc(this.x, this.y, size, 0, 0.5 * Math.PI);
}
parent.addPath(arcPath);
});
}
private drawLevels(path: Path2D): void {
this.levels.forEach((level) => {
// Horizontal lines
const yh =
this.forecasting == Forecasting.Long
? this.y - this.sectionSize * level
: this.y + this.sectionSize * level;
path.moveTo(this.x, yh);
path.lineTo(this.x + this.size, yh);
// Vertical lines
const xv = this.x + this.sectionSize * level;
path.moveTo(xv, this.y);
if (this.forecasting == Forecasting.Long) {
path.lineTo(xv, this.y - this.size);
} else {
path.lineTo(xv, this.y + this.size);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment