There is a task to implement a graph of currency exchange rates in Angular through Canvas The condition of the problem: you can not use the library work with Canvas. From the beauties: when moving, a vertical line should follow the graph and highlight the current point on the curve. Naturally, next to the point should be the numerical value of the course, the date and the difference with the previous day. This is my first application in Angular and TypeScript.
Did data loading through service, with data waiting through Observable . Made two classes. Instances of the CanvasSettings class will contain information about the size, padding and everything related to the Canvas layers. There will be 2 of them, one on top of the other. The first one will contain graphics that should not be redrawn, the second one will specialize specifically on dynamic graphics.
The second class, DatePoints , contains detailed information about the courses, the coordinates of points, the difference with yesterday, and the simplest functions for calculating some data.
Class interaction occurs at app.component.ts . The component parses the information from the source, checks the points for correctness, sorts in order and fills the instance of DatePoints , calculates the initial and final values on the Y scale so that the course curve fits with a small indent from the bottom and from the top, calculates intervals for months and days each month on a scale of X, as well as the even distribution of days in each month (not all trading days and the number of trading days in each month are different).
All questions on architecture. This information failed to google either in ru or en segments of the Network.
Actually questions.
- The most important question is where in the component should the call for rendering functions of the static Canvas layer be placed, and in which dynamic one?
- How to transfer mouse position coordinates over a dynamic layer?
@HostListener('document:mousemove', ['$event'])? If so, how, instead ofdocument:mousemovespecify the listening area forмойCanvasЭлемент:mousemoveeventмойCanvasЭлемент:mousemove? - How to run the function of redrawing a dynamic layer using Angular at a specified interval? If you need to write your throttling function (aka drag ), such as
throttlein lowdash, say so without details, but if this is not the Angular way , then please explain or say google.
Sample code app.component.ts
import { Component, OnInit } from '@angular/core'; import { CanvasSettings } from './canvas-settings'; import { Rate } from './rate'; import { RateService } from './rates.service'; import { DatePoints, Year, Month, Day } from './dates'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers: [RateService] }) export class AppComponent implements OnInit { title = 'Exchange Rates via Canvas'; bgrdCanvas = new CanvasSettings("bgrdCanvas"); // статический слой interactiveCanvas = new CanvasSettings("iaCanvas"); // динамический слой rates: Rate[]; dateArray: DatePoints; constructor(private _rateService: RateService){ } ngOnInit() { this.getRates(); // получаем массив котировок в this.rates this.parseDataArray(); // перебиваем значения в объект this.dateArray, точки, не соответсвующие формату данных, выбрасываем this.organizeArray(); // сортируем, чтобы даты в массивах this.dateArray шли по порядку друг за другом this.setDiffs(); // высчитываем diffы между каждой парой точек в this.dateArray this.calculateCoords(); // вычисляем координаты каждой точки на Canvas слое, учитывая отступы и равномерную разбивку дней внутри каждого месяца this.setAxisExtremums(); } getRates():void { this._rateService.getRates() .subscribe(rates => this.rates = rates); } parseDateFromRate(rate: Rate): Array<number> { //... } parseDataArray():void { //... } organizeArray():void { //... } setDiffs():void { //... } calculateCoords():void { //... } setAxisExtremums():void { //... } drawStaticCanvas():void { // где вызывать? let canvas = document.getElementById(this.bgrdCanvas.idSelector); console.log(canvas); let ctx = canvas.getContext("2d"); } drawDynamicCanvas():void { // где вызывать? Есть ли throttle? //... } }