1 import { AfterViewInit, Component, Input, OnChanges, ViewChild } from '@angular/core';
3 import { CssHelper } from '~/app/shared/classes/css-helper';
4 import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
5 import { DimlessBinaryPerSecondPipe } from '~/app/shared/pipes/dimless-binary-per-second.pipe';
6 import { FormatterService } from '~/app/shared/services/formatter.service';
7 import { BaseChartDirective, PluginServiceGlobalRegistrationAndOptions } from 'ng2-charts';
8 import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe';
9 import { NumberFormatterService } from '~/app/shared/services/number-formatter.service';
12 selector: 'cd-dashboard-area-chart',
13 templateUrl: './dashboard-area-chart.component.html',
14 styleUrls: ['./dashboard-area-chart.component.scss']
16 export class DashboardAreaChartComponent implements OnChanges, AfterViewInit {
17 @ViewChild(BaseChartDirective) chart: BaseChartDirective;
26 data: Array<[number, string]>;
28 data2?: Array<[number, string]>;
34 decimals?: number = 1;
36 currentDataUnits: string;
38 currentDataUnits2?: string;
39 currentData2?: number;
41 chartDataUnits: string;
47 data: [{ x: 0, y: 0 }],
49 pointBackgroundColor: this.cssHelper.propertyValue('chart-color-strong-blue'),
50 backgroundColor: this.cssHelper.propertyValue('chart-color-translucent-blue'),
51 borderColor: this.cssHelper.propertyValue('chart-color-strong-blue')
57 pointBackgroundColor: this.cssHelper.propertyValue('chart-color-orange'),
58 backgroundColor: this.cssHelper.propertyValue('chart-color-yellow'),
59 borderColor: this.cssHelper.propertyValue('chart-color-orange')
66 maintainAspectRatio: false,
76 custom: function (tooltipModel: { x: number; y: number }) {
82 backgroundColor: this.cssHelper.propertyValue('chart-color-tooltip-background'),
84 title: function (tooltipItem: any): any {
85 return tooltipItem[0].xLabel;
101 tooltipFormat: 'YYYY/MM/DD hh:mm:ss'
113 callback: (value: any) => {
117 return this.fillString(this.convertUnits(value));
126 borderColor: this.cssHelper.propertyValue('chart-color-slight-dark-gray'),
132 public chartAreaBorderPlugin: PluginServiceGlobalRegistrationAndOptions[] = [
134 beforeDraw(chart: Chart) {
135 if (!chart.options.plugins.borderArea) {
140 chartArea: { left, top, right, bottom }
143 ctx.strokeStyle = chart.options.plugins.chartAreaBorder.borderColor;
144 ctx.lineWidth = chart.options.plugins.chartAreaBorder.borderWidth;
145 ctx.setLineDash(chart.options.plugins.chartAreaBorder.borderDash || []);
146 ctx.lineDashOffset = chart.options.plugins.chartAreaBorder.borderDashOffset;
147 ctx.strokeRect(left, top, right - left - 1, bottom);
154 private cssHelper: CssHelper,
155 private dimlessBinary: DimlessBinaryPipe,
156 private dimlessBinaryPerSecond: DimlessBinaryPerSecondPipe,
157 private dimlessPipe: DimlessPipe,
158 private formatter: FormatterService,
159 private numberFormatter: NumberFormatterService
162 ngOnChanges(): void {
163 this.updateChartData();
166 ngAfterViewInit(): void {
167 this.updateChartData();
170 private updateChartData(): void {
172 this.setChartTicks();
173 this.chartData.dataset[0].data = this.formatData(this.data);
174 this.chartData.dataset[0].label = this.label;
175 [this.currentData, this.currentDataUnits] = this.convertUnits(
176 this.data[this.data.length - 1][1]
180 this.chartData.dataset[1].data = this.formatData(this.data2);
181 this.chartData.dataset[1].label = this.label2;
182 [this.currentData2, this.currentDataUnits2] = this.convertUnits(
183 this.data2[this.data2.length - 1][1]
187 this.chart.chart.update();
191 private formatData(array: Array<any>): any {
192 let formattedData = {};
193 formattedData = array.map((data: any) => ({
195 y: Number(this.convertToChartDataUnits(data[1]).replace(/[^\d,.]+/g, ''))
197 return formattedData;
200 private convertToChartDataUnits(data: any): any {
201 let dataWithUnits: string = '';
202 if (this.chartDataUnits !== null) {
203 if (this.dataUnits === 'B') {
204 dataWithUnits = this.numberFormatter.formatBytesFromTo(
209 } else if (this.dataUnits === 'B/s') {
210 dataWithUnits = this.numberFormatter.formatBytesPerSecondFromTo(
215 } else if (this.dataUnits === 'ms') {
216 dataWithUnits = this.numberFormatter.formatSecondsFromTo(
223 dataWithUnits = this.numberFormatter.formatUnitlessFromTo(
230 return dataWithUnits;
233 private convertUnits(data: any): any {
234 let dataWithUnits: string = '';
235 if (this.dataUnits === 'B') {
236 dataWithUnits = this.dimlessBinary.transform(data);
237 } else if (this.dataUnits === 'B/s') {
238 dataWithUnits = this.dimlessBinaryPerSecond.transform(data);
239 } else if (this.dataUnits === 'ms') {
240 dataWithUnits = this.formatter.format_number(data, 1000, ['ms', 's'], this.decimals);
242 dataWithUnits = this.dimlessPipe.transform(data);
244 return dataWithUnits;
247 private fillString(str: string): string {
248 let maxNumberOfChar: number = 8;
249 let numberOfChars: number = str.length;
250 if (str.length < 4) {
251 maxNumberOfChar = 11;
253 for (; numberOfChars < maxNumberOfChar; numberOfChars++) {
254 str = '\u00A0' + str;
256 return str + '\u00A0\u00A0';
259 private setChartTicks() {
265 let maxValueDataUnits = '';
270 [maxValue, maxValueDataUnits] = this.convertUnits(this.maxValue).split(' ');
271 } else if (this.data) {
273 let maxValueData = Math.max(...this.data.map((values: any) => values[1]));
275 let maxValueData2 = Math.max(...this.data2.map((values: any) => values[1]));
276 maxValue = Math.max(maxValueData, maxValueData2);
278 maxValue = maxValueData;
280 [maxValue, maxValueDataUnits] = this.convertUnits(maxValue).split(' ');
283 const yAxesTicks = this.chart.chart.options.scales.yAxes[0].ticks;
284 yAxesTicks.suggestedMax = maxValue * extraRoom;
285 yAxesTicks.suggestedMin = 0;
286 yAxesTicks.stepSize = Number((yAxesTicks.suggestedMax / 2).toFixed(0));
287 yAxesTicks.callback = (value: any) => {
291 if (!maxValueDataUnits) {
292 return this.fillString(`${value}`);
294 return this.fillString(`${value} ${maxValueDataUnits}`);
296 this.chartDataUnits = maxValueDataUnits || '';
297 this.chart.chart.update();