1 import { Component, Input, OnChanges, SimpleChanges, 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 {
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;
40 maxConvertedValue?: number;
41 maxConvertedValueUnits?: string;
43 chartDataUnits: string;
47 public chartAreaBorderPlugin: PluginServiceGlobalRegistrationAndOptions[] = [
49 beforeDraw(chart: Chart) {
50 if (!chart.options.plugins.borderArea) {
55 chartArea: { left, top, right, bottom }
58 ctx.strokeStyle = chart.options.plugins.chartAreaBorder.borderColor;
59 ctx.lineWidth = chart.options.plugins.chartAreaBorder.borderWidth;
60 ctx.setLineDash(chart.options.plugins.chartAreaBorder.borderDash || []);
61 ctx.lineDashOffset = chart.options.plugins.chartAreaBorder.borderDashOffset;
62 ctx.strokeRect(left, top, right - left - 1, bottom);
69 private cssHelper: CssHelper,
70 private dimlessBinary: DimlessBinaryPipe,
71 private dimlessBinaryPerSecond: DimlessBinaryPerSecondPipe,
72 private dimlessPipe: DimlessPipe,
73 private formatter: FormatterService,
74 private numberFormatter: NumberFormatterService
80 data: [{ x: 0, y: 0 }],
82 pointBackgroundColor: this.cssHelper.propertyValue('chart-color-strong-blue'),
83 backgroundColor: this.cssHelper.propertyValue('chart-color-translucent-blue'),
84 borderColor: this.cssHelper.propertyValue('chart-color-strong-blue'),
91 pointBackgroundColor: this.cssHelper.propertyValue('chart-color-orange'),
92 backgroundColor: this.cssHelper.propertyValue('chart-color-translucent-yellow'),
93 borderColor: this.cssHelper.propertyValue('chart-color-orange'),
101 maintainAspectRatio: false,
113 custom: function (tooltipModel: { x: number; y: number }) {
119 backgroundColor: this.cssHelper.propertyValue('chart-color-tooltip-background'),
121 title: function (tooltipItem: any): any {
122 return tooltipItem[0].xLabel;
124 label: (tooltipItems: any, data: any) => {
127 data.datasets[tooltipItems.datasetIndex].label +
148 tooltipFormat: 'DD/MM/YYYY - HH:mm:ss'
154 afterFit: (scaleInstance: any) => (scaleInstance.width = 100),
161 callback: (value: any) => {
165 return this.convertUnits(value);
174 borderColor: this.cssHelper.propertyValue('chart-color-slight-dark-gray'),
181 ngOnChanges(changes: SimpleChanges): void {
182 this.updateChartData(changes);
185 private updateChartData(changes: SimpleChanges): void {
186 this.chartData.dataset[0].label = this.label;
187 this.chartData.dataset[1].label = this.label2;
188 this.setChartTicks();
189 if (changes.data && changes.data.currentValue) {
190 this.data = changes.data.currentValue;
191 this.chartData.dataset[0].data = this.formatData(this.data);
192 [this.currentData, this.currentDataUnits] = this.convertUnits(
193 this.data[this.data.length - 1][1]
195 [this.maxConvertedValue, this.maxConvertedValueUnits] = this.convertUnits(
199 if (changes.data2 && changes.data2.currentValue) {
200 this.data2 = changes.data2.currentValue;
201 this.chartData.dataset[1].data = this.formatData(this.data2);
202 [this.currentData2, this.currentDataUnits2] = this.convertUnits(
203 this.data2[this.data2.length - 1][1]
207 this.chart.chart.update();
211 private formatData(array: Array<any>): any {
212 let formattedData = {};
213 formattedData = array.map((data: any) => ({
215 y: Number(this.convertToChartDataUnits(data[1]).replace(/[^\d,.]+/g, ''))
217 return formattedData;
220 private convertToChartDataUnits(data: any): any {
221 let dataWithUnits: string = '';
222 if (this.chartDataUnits !== null) {
223 if (this.dataUnits === 'B') {
224 dataWithUnits = this.numberFormatter.formatBytesFromTo(
230 } else if (this.dataUnits === 'B/s') {
231 dataWithUnits = this.numberFormatter.formatBytesPerSecondFromTo(
237 } else if (this.dataUnits === 'ms') {
238 dataWithUnits = this.numberFormatter.formatSecondsFromTo(
245 dataWithUnits = this.numberFormatter.formatUnitlessFromTo(
253 return dataWithUnits;
256 private convertUnits(data: any): any {
257 let dataWithUnits: string = '';
258 if (this.dataUnits === 'B') {
259 dataWithUnits = this.dimlessBinary.transform(data, this.decimals);
260 } else if (this.dataUnits === 'B/s') {
261 dataWithUnits = this.dimlessBinaryPerSecond.transform(data, this.decimals);
262 } else if (this.dataUnits === 'ms') {
263 dataWithUnits = this.formatter.format_number(data, 1000, ['ms', 's'], this.decimals);
265 dataWithUnits = this.dimlessPipe.transform(data, this.decimals);
267 return dataWithUnits;
270 private setChartTicks() {
276 let maxValueDataUnits = '';
280 let maxValueData = Math.max(...this.data.map((values: any) => values[1]));
282 let maxValueData2 = Math.max(...this.data2.map((values: any) => values[1]));
283 maxValue = Math.max(maxValueData, maxValueData2);
285 maxValue = maxValueData;
287 [maxValue, maxValueDataUnits] = this.convertUnits(maxValue).split(' ');
290 const yAxesTicks = this.chart.chart.options.scales.yAxes[0].ticks;
291 yAxesTicks.suggestedMax = maxValue * extraRoom;
292 yAxesTicks.suggestedMin = 0;
293 yAxesTicks.callback = (value: any) => {
297 if (!maxValueDataUnits) {
300 return `${value} ${maxValueDataUnits}`;
302 this.chartDataUnits = maxValueDataUnits || '';
303 this.chart.chart.update();