ipsos-components
Version:
Material Design components for Angular
97 lines (76 loc) • 3.55 kB
text/typescript
import {ChangeDetectionStrategy, Component, Input} from '@angular/core';
import {CoverageEntries, CoverageResult} from '../data-definitions';
import {NgxChartResult} from '../ngx-definitions';
({
selector: 'coverage-chart',
templateUrl: './coverage-chart.html',
styleUrls: ['./coverage-chart.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
'class': 'dashboard-panel'
}
})
export class CoverageChart {
/** Color scheme for the coverage graph. */
colorScheme = {
domain: ['#5AA454', '#A10A28', '#C7B42C', '#AAAAAA']
};
/** X-Axis label of the Chart. */
xAxisLabel = 'Date';
/** Y-Axis label of the Chart. */
yAxisLabel = 'Coverage Percentage (%)';
/** Chart data that is taken by NGX-Charts. */
chartData: NgxChartResult[];
/** Coverage data that will be rendered in the chart. */
()
set data(value: CoverageResult[]) {
this.chartData = this.createChartResults(value);
}
/** Remove duplicate coverage results for similar days. */
private filterDuplicateDays(data: CoverageResult[]) {
const filteredData = new Map<string, CoverageResult>();
data.forEach(result => {
// Parse the timestamp from the coverage result as a date.
const date = new Date(result.timestamp);
// Ignore hours, minutes, seconds and milliseconds from the date to allow comparisons
// only of the day.
date.setHours(0, 0, 0, 0);
// Store the ISO string of the date in a Map to overwrite the previous coverage result for
// the same day.
filteredData.set(date.toISOString(), result);
});
return Array.from(filteredData.values());
}
/** Creates a list of ngx-chart results of the coverage results. */
private createChartResults(data: CoverageResult[]) {
if (!data) {
return [];
}
// In the early stages of the coverage reports that will be uploaded to Firebase, the timestamp
// was not added to the reports. All old results need to be filtered out for the chart.
data = data.filter(result => result.timestamp);
// Data snapshot from Firebase is not ordered by timestamp. Before rendering the graph
// manually sort the results by their timestamp.
data = data.sort((a, b) => a.timestamp < b.timestamp ? -1 : 1);
// It can happen that there will be multiple coverage reports for the same day. This happens
// if multiple PRs are merged at the same day. For the charts we only want to
// have the last coverage report of a day (for performance and value correctness)
data = this.filterDuplicateDays(data);
return [
{ name: 'Lines', series: this.createCoverageChartItems(data, 'lines') },
{ name: 'Branches', series: this.createCoverageChartItems(data, 'branches') },
{ name: 'Functions', series: this.createCoverageChartItems(data, 'functions') },
{ name: 'Statements', series: this.createCoverageChartItems(data, 'statements') }
];
}
/** Creates a list of items for NGX-Charts that represent a coverage entry type. */
private createCoverageChartItems(data: CoverageResult[], entryType: CoverageEntries) {
return data.map(result => {
const entryResult = result[entryType];
// Convert the timestamp of the coverage result into a date because NGX-Charts can group
// dates in the x-axis.
const date = new Date(result.timestamp);
return { name: date, value: entryResult.pct };
});
}
}