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 currentDataUnits: string;
36 currentDataUnits2?: string;
37 currentData2?: number;
39 chartDataUnits: string;
45 data: [{ x: 0, y: 0 }],
47 pointBackgroundColor: this.cssHelper.propertyValue('chart-color-strong-blue'),
48 backgroundColor: this.cssHelper.propertyValue('chart-color-translucent-blue'),
49 borderColor: this.cssHelper.propertyValue('chart-color-strong-blue')
55 pointBackgroundColor: this.cssHelper.propertyValue('chart-color-orange'),
56 backgroundColor: this.cssHelper.propertyValue('chart-color-yellow'),
57 borderColor: this.cssHelper.propertyValue('chart-color-orange')
64 maintainAspectRatio: false,
76 backgroundColor: this.cssHelper.propertyValue('chart-color-tooltip-background'),
78 title: function (tooltipItem: any): any {
79 return tooltipItem[0].xLabel;
95 tooltipFormat: 'YYYY/MM/DD hh:mm:ss'
107 callback: (value: any) => {
111 return this.fillString(this.convertUnits(value));
120 borderColor: this.cssHelper.propertyValue('chart-color-slight-dark-gray'),
126 public chartAreaBorderPlugin: PluginServiceGlobalRegistrationAndOptions[] = [
128 beforeDraw(chart: Chart) {
129 if (!chart.options.plugins.borderArea) {
134 chartArea: { left, top, right, bottom }
137 ctx.strokeStyle = chart.options.plugins.chartAreaBorder.borderColor;
138 ctx.lineWidth = chart.options.plugins.chartAreaBorder.borderWidth;
139 ctx.setLineDash(chart.options.plugins.chartAreaBorder.borderDash || []);
140 ctx.lineDashOffset = chart.options.plugins.chartAreaBorder.borderDashOffset;
141 ctx.strokeRect(left, top, right - left - 1, bottom);
148 private cssHelper: CssHelper,
149 private dimlessBinary: DimlessBinaryPipe,
150 private dimlessBinaryPerSecond: DimlessBinaryPerSecondPipe,
151 private dimlessPipe: DimlessPipe,
152 private formatter: FormatterService,
153 private numberFormatter: NumberFormatterService
156 ngOnChanges(): void {
157 this.updateChartData();
160 ngAfterViewInit(): void {
161 this.updateChartData();
164 private updateChartData(): void {
166 this.setChartTicks();
167 this.chartData.dataset[0].data = this.formatData(this.data);
168 this.chartData.dataset[0].label = this.label;
169 [this.currentData, this.currentDataUnits] = this.convertUnits(
170 this.data[this.data.length - 1][1]
174 this.chartData.dataset[1].data = this.formatData(this.data2);
175 this.chartData.dataset[1].label = this.label2;
176 [this.currentData2, this.currentDataUnits2] = this.convertUnits(
177 this.data2[this.data2.length - 1][1]
181 this.chart.chart.update();
185 private formatData(array: Array<any>): any {
186 let formattedData = {};
187 formattedData = array.map((data: any) => ({
189 y: Number(this.convertToChartDataUnits(data[1]).replace(/[^\d,.]+/g, ''))
191 return formattedData;
194 private convertToChartDataUnits(data: any): any {
195 let dataWithUnits: string = '';
196 if (this.chartDataUnits) {
197 if (this.dataUnits === 'B') {
198 dataWithUnits = this.numberFormatter.formatBytesFromTo(
203 } else if (this.dataUnits === 'B/s') {
204 dataWithUnits = this.numberFormatter.formatBytesPerSecondFromTo(
209 } else if (this.dataUnits === 'ms') {
210 dataWithUnits = this.numberFormatter.formatSecondsFromTo(
216 dataWithUnits = this.numberFormatter.formatUnitlessFromTo(
223 return dataWithUnits;
226 private convertUnits(data: any): any {
227 let dataWithUnits: string = '';
228 if (this.dataUnits === 'B') {
229 dataWithUnits = this.dimlessBinary.transform(data);
230 } else if (this.dataUnits === 'B/s') {
231 dataWithUnits = this.dimlessBinaryPerSecond.transform(data);
232 } else if (this.dataUnits === 'ms') {
233 dataWithUnits = this.formatter.format_number(data, 1000, ['ms', 's']);
235 dataWithUnits = this.dimlessPipe.transform(data);
237 return dataWithUnits;
240 private fillString(str: string): string {
241 let maxNumberOfChar: number = 8;
242 let numberOfChars: number = str.length;
243 if (str.length < 4) {
244 maxNumberOfChar = 11;
246 for (; numberOfChars < maxNumberOfChar; numberOfChars++) {
247 str = '\u00A0' + str;
249 return str + '\u00A0\u00A0';
252 private setChartTicks() {
258 let maxValueDataUnits = '';
263 [maxValue, maxValueDataUnits] = this.convertUnits(this.maxValue).split(' ');
264 } else if (this.data) {
266 let maxValueData = Math.max(...this.data.map((values: any) => values[1]));
268 let maxValueData2 = Math.max(...this.data2.map((values: any) => values[1]));
269 maxValue = Math.max(maxValueData, maxValueData2);
271 maxValue = maxValueData;
273 [maxValue, maxValueDataUnits] = this.convertUnits(maxValue).split(' ');
276 const yAxesTicks = this.chart.chart.options.scales.yAxes[0].ticks;
277 yAxesTicks.suggestedMax = maxValue * extraRoom;
278 yAxesTicks.suggestedMin = 0;
279 yAxesTicks.stepSize = Number((yAxesTicks.suggestedMax / 2).toFixed(0));
280 yAxesTicks.callback = (value: any) => {
284 if (!maxValueDataUnits) {
285 return this.fillString(`${value}`);
287 return this.fillString(`${value} ${maxValueDataUnits}`);
289 this.chartDataUnits = maxValueDataUnits || '';
290 this.chart.chart.update();