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,
78 backgroundColor: this.cssHelper.propertyValue('chart-color-tooltip-background'),
80 title: function (tooltipItem: any): any {
81 return tooltipItem[0].xLabel;
97 tooltipFormat: 'YYYY/MM/DD hh:mm:ss'
109 callback: (value: any) => {
113 return this.fillString(this.convertUnits(value));
122 borderColor: this.cssHelper.propertyValue('chart-color-slight-dark-gray'),
128 public chartAreaBorderPlugin: PluginServiceGlobalRegistrationAndOptions[] = [
130 beforeDraw(chart: Chart) {
131 if (!chart.options.plugins.borderArea) {
136 chartArea: { left, top, right, bottom }
139 ctx.strokeStyle = chart.options.plugins.chartAreaBorder.borderColor;
140 ctx.lineWidth = chart.options.plugins.chartAreaBorder.borderWidth;
141 ctx.setLineDash(chart.options.plugins.chartAreaBorder.borderDash || []);
142 ctx.lineDashOffset = chart.options.plugins.chartAreaBorder.borderDashOffset;
143 ctx.strokeRect(left, top, right - left - 1, bottom);
150 private cssHelper: CssHelper,
151 private dimlessBinary: DimlessBinaryPipe,
152 private dimlessBinaryPerSecond: DimlessBinaryPerSecondPipe,
153 private dimlessPipe: DimlessPipe,
154 private formatter: FormatterService,
155 private numberFormatter: NumberFormatterService
158 ngOnChanges(): void {
159 this.updateChartData();
162 ngAfterViewInit(): void {
163 this.updateChartData();
166 private updateChartData(): void {
168 this.setChartTicks();
169 this.chartData.dataset[0].data = this.formatData(this.data);
170 this.chartData.dataset[0].label = this.label;
171 [this.currentData, this.currentDataUnits] = this.convertUnits(
172 this.data[this.data.length - 1][1]
176 this.chartData.dataset[1].data = this.formatData(this.data2);
177 this.chartData.dataset[1].label = this.label2;
178 [this.currentData2, this.currentDataUnits2] = this.convertUnits(
179 this.data2[this.data2.length - 1][1]
183 this.chart.chart.update();
187 private formatData(array: Array<any>): any {
188 let formattedData = {};
189 formattedData = array.map((data: any) => ({
191 y: Number(this.convertToChartDataUnits(data[1]).replace(/[^\d,.]+/g, ''))
193 return formattedData;
196 private convertToChartDataUnits(data: any): any {
197 let dataWithUnits: string = '';
198 if (this.chartDataUnits) {
199 if (this.dataUnits === 'B') {
200 dataWithUnits = this.numberFormatter.formatBytesFromTo(
205 } else if (this.dataUnits === 'B/s') {
206 dataWithUnits = this.numberFormatter.formatBytesPerSecondFromTo(
211 } else if (this.dataUnits === 'ms') {
212 dataWithUnits = this.numberFormatter.formatSecondsFromTo(
219 dataWithUnits = this.numberFormatter.formatUnitlessFromTo(
226 return dataWithUnits;
229 private convertUnits(data: any): any {
230 let dataWithUnits: string = '';
231 if (this.dataUnits === 'B') {
232 dataWithUnits = this.dimlessBinary.transform(data);
233 } else if (this.dataUnits === 'B/s') {
234 dataWithUnits = this.dimlessBinaryPerSecond.transform(data);
235 } else if (this.dataUnits === 'ms') {
236 dataWithUnits = this.formatter.format_number(data, 1000, ['ms', 's'], this.decimals);
238 dataWithUnits = this.dimlessPipe.transform(data);
240 return dataWithUnits;
243 private fillString(str: string): string {
244 let maxNumberOfChar: number = 8;
245 let numberOfChars: number = str.length;
246 if (str.length < 4) {
247 maxNumberOfChar = 11;
249 for (; numberOfChars < maxNumberOfChar; numberOfChars++) {
250 str = '\u00A0' + str;
252 return str + '\u00A0\u00A0';
255 private setChartTicks() {
261 let maxValueDataUnits = '';
266 [maxValue, maxValueDataUnits] = this.convertUnits(this.maxValue).split(' ');
267 } else if (this.data) {
269 let maxValueData = Math.max(...this.data.map((values: any) => values[1]));
271 let maxValueData2 = Math.max(...this.data2.map((values: any) => values[1]));
272 maxValue = Math.max(maxValueData, maxValueData2);
274 maxValue = maxValueData;
276 [maxValue, maxValueDataUnits] = this.convertUnits(maxValue).split(' ');
279 const yAxesTicks = this.chart.chart.options.scales.yAxes[0].ticks;
280 yAxesTicks.suggestedMax = maxValue * extraRoom;
281 yAxesTicks.suggestedMin = 0;
282 yAxesTicks.stepSize = Number((yAxesTicks.suggestedMax / 2).toFixed(0));
283 yAxesTicks.callback = (value: any) => {
287 if (!maxValueDataUnits) {
288 return this.fillString(`${value}`);
290 return this.fillString(`${value} ${maxValueDataUnits}`);
292 this.chartDataUnits = maxValueDataUnits || '';
293 this.chart.chart.update();