Commit d9fb45d6 authored by Brandon Labuschagne's avatar Brandon Labuschagne Committed by Phil Hughes

Add everage to CI/CD deployment chart

This commit adds an average line to the
CI/CD deployment freguency chart

Changelog: added
EE: true
parent 138725b9
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import * as DoraApi from 'ee/api/dora_api'; import * as DoraApi from 'ee/api/dora_api';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { s__ } from '~/locale'; import { s__, sprintf } from '~/locale';
import CiCdAnalyticsCharts from '~/vue_shared/components/ci_cd_analytics/ci_cd_analytics_charts.vue'; import CiCdAnalyticsCharts from '~/vue_shared/components/ci_cd_analytics/ci_cd_analytics_charts.vue';
import DoraChartHeader from './dora_chart_header.vue'; import DoraChartHeader from './dora_chart_header.vue';
import { import {
allChartDefinitions, allChartDefinitions,
areaChartOptions, areaChartOptions,
averageSeriesOptions,
averageSeriesName,
chartDescriptionText, chartDescriptionText,
chartDocumentationHref, chartDocumentationHref,
LAST_WEEK, LAST_WEEK,
...@@ -15,7 +17,7 @@ import { ...@@ -15,7 +17,7 @@ import {
LAST_90_DAYS, LAST_90_DAYS,
CHART_TITLE, CHART_TITLE,
} from './static_data/deployment_frequency'; } from './static_data/deployment_frequency';
import { apiDataToChartSeries } from './util'; import { apiDataToChartSeries, seriesToAverageSeries } from './util';
export default { export default {
name: 'DeploymentFrequencyCharts', name: 'DeploymentFrequencyCharts',
...@@ -33,6 +35,11 @@ export default { ...@@ -33,6 +35,11 @@ export default {
default: '', default: '',
}, },
}, },
chartInDays: {
[LAST_WEEK]: 7,
[LAST_MONTH]: 30,
[LAST_90_DAYS]: 90,
},
data() { data() {
return { return {
chartData: { chartData: {
...@@ -76,7 +83,19 @@ export default { ...@@ -76,7 +83,19 @@ export default {
throw new Error('Either projectPath or groupPath must be provided'); throw new Error('Either projectPath or groupPath must be provided');
} }
this.chartData[id] = apiDataToChartSeries(apiData, startDate, endDate, CHART_TITLE); const seriesData = apiDataToChartSeries(apiData, startDate, endDate, CHART_TITLE);
const { data } = seriesData[0];
this.chartData[id] = [
...seriesData,
{
...averageSeriesOptions,
...seriesToAverageSeries(
data,
sprintf(averageSeriesName, { days: this.$options.chartInDays[id] }),
),
},
];
}), }),
); );
......
...@@ -3,6 +3,8 @@ import { s__ } from '~/locale'; ...@@ -3,6 +3,8 @@ import { s__ } from '~/locale';
export * from './shared'; export * from './shared';
export const averageSeriesName = s__('DORA4Metrics|Average (last %{days}d)');
export const CHART_TITLE = s__('DORA4Metrics|Deployment frequency'); export const CHART_TITLE = s__('DORA4Metrics|Deployment frequency');
export const areaChartOptions = { export const areaChartOptions = {
......
...@@ -36,6 +36,12 @@ const sharedRequestParams = { ...@@ -36,6 +36,12 @@ const sharedRequestParams = {
per_page: 100, per_page: 100,
}; };
export const averageSeriesOptions = {
areaStyle: {
opacity: 0,
},
};
export const allChartDefinitions = [ export const allChartDefinitions = [
{ {
id: LAST_WEEK, id: LAST_WEEK,
......
...@@ -147,3 +147,24 @@ export const buildNullSeriesForLeadTimeChart = (seriesData) => { ...@@ -147,3 +147,24 @@ export const buildNullSeriesForLeadTimeChart = (seriesData) => {
return [nullSeries, nonNullSeries]; return [nullSeries, nonNullSeries];
}; };
/**
* Converts a data series into a formatted average series
*
* @param {Array} chartSeriesData Correctly formatted chart series data
*
* @returns {Object} An object containing the series name and an array of original data keys with the average of the dataset as each value.
*/
export const seriesToAverageSeries = (chartSeriesData, seriesName) => {
if (!chartSeriesData) return {};
const average =
Math.round(
(chartSeriesData.reduce((acc, day) => acc + day[1], 0) / chartSeriesData.length) * 10,
) / 10;
return {
name: seriesName,
data: chartSeriesData.map((day) => [day[0], average]),
};
};
...@@ -37,6 +37,42 @@ Array [ ...@@ -37,6 +37,42 @@ Array [
], ],
"name": "Deployment frequency", "name": "Deployment frequency",
}, },
Object {
"areaStyle": Object {
"opacity": 0,
},
"data": Array [
Array [
"Jun 27",
0.7,
],
Array [
"Jun 28",
0.7,
],
Array [
"Jun 29",
0.7,
],
Array [
"Jun 30",
0.7,
],
Array [
"Jul 1",
0.7,
],
Array [
"Jul 2",
0.7,
],
Array [
"Jul 3",
0.7,
],
],
"name": "Average (last 7d)",
},
], ],
"endDate": 2015-07-04T00:00:00.000Z, "endDate": 2015-07-04T00:00:00.000Z,
"id": "LAST_WEEK", "id": "LAST_WEEK",
...@@ -177,6 +213,134 @@ Array [ ...@@ -177,6 +213,134 @@ Array [
], ],
"name": "Deployment frequency", "name": "Deployment frequency",
}, },
Object {
"areaStyle": Object {
"opacity": 0,
},
"data": Array [
Array [
"Jun 4",
0.2,
],
Array [
"Jun 5",
0.2,
],
Array [
"Jun 6",
0.2,
],
Array [
"Jun 7",
0.2,
],
Array [
"Jun 8",
0.2,
],
Array [
"Jun 9",
0.2,
],
Array [
"Jun 10",
0.2,
],
Array [
"Jun 11",
0.2,
],
Array [
"Jun 12",
0.2,
],
Array [
"Jun 13",
0.2,
],
Array [
"Jun 14",
0.2,
],
Array [
"Jun 15",
0.2,
],
Array [
"Jun 16",
0.2,
],
Array [
"Jun 17",
0.2,
],
Array [
"Jun 18",
0.2,
],
Array [
"Jun 19",
0.2,
],
Array [
"Jun 20",
0.2,
],
Array [
"Jun 21",
0.2,
],
Array [
"Jun 22",
0.2,
],
Array [
"Jun 23",
0.2,
],
Array [
"Jun 24",
0.2,
],
Array [
"Jun 25",
0.2,
],
Array [
"Jun 26",
0.2,
],
Array [
"Jun 27",
0.2,
],
Array [
"Jun 28",
0.2,
],
Array [
"Jun 29",
0.2,
],
Array [
"Jun 30",
0.2,
],
Array [
"Jul 1",
0.2,
],
Array [
"Jul 2",
0.2,
],
Array [
"Jul 3",
0.2,
],
],
"name": "Average (last 30d)",
},
], ],
"endDate": 2015-07-04T00:00:00.000Z, "endDate": 2015-07-04T00:00:00.000Z,
"id": "LAST_MONTH", "id": "LAST_MONTH",
...@@ -557,6 +721,374 @@ Array [ ...@@ -557,6 +721,374 @@ Array [
], ],
"name": "Deployment frequency", "name": "Deployment frequency",
}, },
Object {
"areaStyle": Object {
"opacity": 0,
},
"data": Array [
Array [
"Apr 5",
0.1,
],
Array [
"Apr 6",
0.1,
],
Array [
"Apr 7",
0.1,
],
Array [
"Apr 8",
0.1,
],
Array [
"Apr 9",
0.1,
],
Array [
"Apr 10",
0.1,
],
Array [
"Apr 11",
0.1,
],
Array [
"Apr 12",
0.1,
],
Array [
"Apr 13",
0.1,
],
Array [
"Apr 14",
0.1,
],
Array [
"Apr 15",
0.1,
],
Array [
"Apr 16",
0.1,
],
Array [
"Apr 17",
0.1,
],
Array [
"Apr 18",
0.1,
],
Array [
"Apr 19",
0.1,
],
Array [
"Apr 20",
0.1,
],
Array [
"Apr 21",
0.1,
],
Array [
"Apr 22",
0.1,
],
Array [
"Apr 23",
0.1,
],
Array [
"Apr 24",
0.1,
],
Array [
"Apr 25",
0.1,
],
Array [
"Apr 26",
0.1,
],
Array [
"Apr 27",
0.1,
],
Array [
"Apr 28",
0.1,
],
Array [
"Apr 29",
0.1,
],
Array [
"Apr 30",
0.1,
],
Array [
"May 1",
0.1,
],
Array [
"May 2",
0.1,
],
Array [
"May 3",
0.1,
],
Array [
"May 4",
0.1,
],
Array [
"May 5",
0.1,
],
Array [
"May 6",
0.1,
],
Array [
"May 7",
0.1,
],
Array [
"May 8",
0.1,
],
Array [
"May 9",
0.1,
],
Array [
"May 10",
0.1,
],
Array [
"May 11",
0.1,
],
Array [
"May 12",
0.1,
],
Array [
"May 13",
0.1,
],
Array [
"May 14",
0.1,
],
Array [
"May 15",
0.1,
],
Array [
"May 16",
0.1,
],
Array [
"May 17",
0.1,
],
Array [
"May 18",
0.1,
],
Array [
"May 19",
0.1,
],
Array [
"May 20",
0.1,
],
Array [
"May 21",
0.1,
],
Array [
"May 22",
0.1,
],
Array [
"May 23",
0.1,
],
Array [
"May 24",
0.1,
],
Array [
"May 25",
0.1,
],
Array [
"May 26",
0.1,
],
Array [
"May 27",
0.1,
],
Array [
"May 28",
0.1,
],
Array [
"May 29",
0.1,
],
Array [
"May 30",
0.1,
],
Array [
"May 31",
0.1,
],
Array [
"Jun 1",
0.1,
],
Array [
"Jun 2",
0.1,
],
Array [
"Jun 3",
0.1,
],
Array [
"Jun 4",
0.1,
],
Array [
"Jun 5",
0.1,
],
Array [
"Jun 6",
0.1,
],
Array [
"Jun 7",
0.1,
],
Array [
"Jun 8",
0.1,
],
Array [
"Jun 9",
0.1,
],
Array [
"Jun 10",
0.1,
],
Array [
"Jun 11",
0.1,
],
Array [
"Jun 12",
0.1,
],
Array [
"Jun 13",
0.1,
],
Array [
"Jun 14",
0.1,
],
Array [
"Jun 15",
0.1,
],
Array [
"Jun 16",
0.1,
],
Array [
"Jun 17",
0.1,
],
Array [
"Jun 18",
0.1,
],
Array [
"Jun 19",
0.1,
],
Array [
"Jun 20",
0.1,
],
Array [
"Jun 21",
0.1,
],
Array [
"Jun 22",
0.1,
],
Array [
"Jun 23",
0.1,
],
Array [
"Jun 24",
0.1,
],
Array [
"Jun 25",
0.1,
],
Array [
"Jun 26",
0.1,
],
Array [
"Jun 27",
0.1,
],
Array [
"Jun 28",
0.1,
],
Array [
"Jun 29",
0.1,
],
Array [
"Jun 30",
0.1,
],
Array [
"Jul 1",
0.1,
],
Array [
"Jul 2",
0.1,
],
Array [
"Jul 3",
0.1,
],
],
"name": "Average (last 90d)",
},
], ],
"endDate": 2015-07-04T00:00:00.000Z, "endDate": 2015-07-04T00:00:00.000Z,
"id": "LAST_90_DAYS", "id": "LAST_90_DAYS",
......
import lastWeekData from 'test_fixtures/api/dora/metrics/daily_lead_time_for_changes_for_last_week.json'; import lastWeekData from 'test_fixtures/api/dora/metrics/daily_lead_time_for_changes_for_last_week.json';
import { apiDataToChartSeries, buildNullSeriesForLeadTimeChart } from 'ee/dora/components/util'; import {
apiDataToChartSeries,
buildNullSeriesForLeadTimeChart,
seriesToAverageSeries,
} from 'ee/dora/components/util';
describe('ee/dora/components/util.js', () => { describe('ee/dora/components/util.js', () => {
describe('apiDataToChartSeries', () => { describe('apiDataToChartSeries', () => {
...@@ -209,4 +213,40 @@ describe('ee/dora/components/util.js', () => { ...@@ -209,4 +213,40 @@ describe('ee/dora/components/util.js', () => {
expect(chartData).toMatchSnapshot(); expect(chartData).toMatchSnapshot();
}); });
}); });
describe('seriesToAverageSeries', () => {
const seriesName = 'Average';
it('returns an empty object if chart data is undefined', () => {
const data = seriesToAverageSeries(undefined, seriesName);
expect(data).toStrictEqual({});
});
it('returns an empty object if chart data is blank', () => {
const data = seriesToAverageSeries(null, seriesName);
expect(data).toStrictEqual({});
});
it('returns the correct average values', () => {
const data = seriesToAverageSeries(
[
['Jul 1', 2],
['Jul 2', 3],
['Jul 3', 4],
],
seriesName,
);
expect(data).toStrictEqual({
name: seriesName,
data: [
['Jul 1', 3],
['Jul 2', 3],
['Jul 3', 3],
],
});
});
});
}); });
...@@ -10796,6 +10796,9 @@ msgstr "" ...@@ -10796,6 +10796,9 @@ msgstr ""
msgid "DORA4Metrics|%{startDate} - %{endDate}" msgid "DORA4Metrics|%{startDate} - %{endDate}"
msgstr "" msgstr ""
msgid "DORA4Metrics|Average (last %{days}d)"
msgstr ""
msgid "DORA4Metrics|Date" msgid "DORA4Metrics|Date"
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment