Commit e0e12ea1 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'add-utils-methods-for-ca-duration-chart-median-line' into 'master'

Add cycle analytics median line data utils

See merge request gitlab-org/gitlab!22802
parents 6785d144 13c665fa
...@@ -2,7 +2,15 @@ import { isString, isNumber } from 'underscore'; ...@@ -2,7 +2,15 @@ import { isString, isNumber } from 'underscore';
import dateFormat from 'dateformat'; import dateFormat from 'dateformat';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { convertToSnakeCase } from '~/lib/utils/text_utility'; import { convertToSnakeCase } from '~/lib/utils/text_utility';
import { newDate, dayAfter, secondsToDays, getDatesInRange } from '~/lib/utils/datetime_utility'; import {
newDate,
dayAfter,
secondsToDays,
getDatesInRange,
getDayDifference,
getDateInPast,
getDateInFuture,
} from '~/lib/utils/datetime_utility';
import { dateFormats } from '../shared/constants'; import { dateFormats } from '../shared/constants';
import { STAGE_NAME } from './constants'; import { STAGE_NAME } from './constants';
import { toYmd } from '../shared/utils'; import { toYmd } from '../shared/utils';
...@@ -173,7 +181,7 @@ export const flattenDurationChartData = data => ...@@ -173,7 +181,7 @@ export const flattenDurationChartData = data =>
* *
* @param {Array} data - The duration data for selected stages * @param {Array} data - The duration data for selected stages
* @param {Date} startDate - The globally selected cycle analytics start date * @param {Date} startDate - The globally selected cycle analytics start date
* @param {Date} endDate - The globally selected cycle analytics stendart date * @param {Date} endDate - The globally selected cycle analytics end date
* @returns {Array} An array with each item being another arry of three items (plottable date, computed total, tooltip display date) * @returns {Array} An array with each item being another arry of three items (plottable date, computed total, tooltip display date)
*/ */
export const getDurationChartData = (data, startDate, endDate) => { export const getDurationChartData = (data, startDate, endDate) => {
...@@ -196,6 +204,42 @@ export const getDurationChartData = (data, startDate, endDate) => { ...@@ -196,6 +204,42 @@ export const getDurationChartData = (data, startDate, endDate) => {
return eventData; return eventData;
}; };
/**
* Takes the offset duration data for selected stages and calls getDurationChartData to compute the totals.
* The data is then transformed into a format expected by the scatterplot;
*
* [
* ['2019-09-02', 7],
* ...
* ]
*
* The transformation works by calling getDateInPast on the provided startDate and endDate in order to match
* the startDate and endDate fetched when making the API call to fetch the data.
*
* In order to map the offset data to plottable points within the chart's range, getDateInFuture is called
* on the data series with the same offest used for getDateInPast. This creates plottable data that matches up
* with the data being displayed on the chart.
*
* @param {Array} data - The computed, plottable duration chart data
* @param {Date} startDate - The globally selected cycle analytics start date
* @param {Date} endDate - The globally selected cycle analytics end date
* @returns {Array} An array with each item being another arry of two items (date, computed total)
*/
export const getDurationChartMedianData = (data, startDate, endDate) => {
const offsetValue = getDayDifference(startDate, endDate);
const offsetEndDate = getDateInPast(endDate, offsetValue);
const offsetStartDate = getDateInPast(startDate, offsetValue);
const offsetDurationData = getDurationChartData(data, offsetStartDate, offsetEndDate);
const result = offsetDurationData.map(event => [
dateFormat(getDateInFuture(new Date(event[0]), offsetValue), dateFormats.isoDate),
event[1],
]);
return result;
};
export const orderByDate = (a, b, dateFmt = datetime => new Date(datetime).getTime()) => export const orderByDate = (a, b, dateFmt = datetime => new Date(datetime).getTime()) =>
dateFmt(a) - dateFmt(b); dateFmt(a) - dateFmt(b);
......
...@@ -174,3 +174,29 @@ export const durationChartPlottableData = [ ...@@ -174,3 +174,29 @@ export const durationChartPlottableData = [
['2019-01-01', 29, '2019-01-01'], ['2019-01-01', 29, '2019-01-01'],
['2019-01-02', 100, '2019-01-02'], ['2019-01-02', 100, '2019-01-02'],
]; ];
export const rawDurationMedianData = [
{
duration_in_seconds: 1234000,
finished_at: '2018-12-01T00:00:00.000Z',
},
{
duration_in_seconds: 4321000,
finished_at: '2018-12-02T00:00:00.000Z',
},
];
export const transformedDurationMedianData = [
{
slug: 1,
selected: true,
data: rawDurationMedianData,
},
{
slug: 2,
selected: true,
data: rawDurationMedianData,
},
];
export const durationChartPlottableMedianData = [['2018-12-31', 29], ['2019-01-01', 100]];
...@@ -10,6 +10,7 @@ import { ...@@ -10,6 +10,7 @@ import {
nestQueryStringKeys, nestQueryStringKeys,
flattenDurationChartData, flattenDurationChartData,
getDurationChartData, getDurationChartData,
getDurationChartMedianData,
transformRawStages, transformRawStages,
isPersistedStage, isPersistedStage,
getTasksByTypeData, getTasksByTypeData,
...@@ -23,8 +24,10 @@ import { ...@@ -23,8 +24,10 @@ import {
labelStopEvent, labelStopEvent,
customStageStartEvents as startEvents, customStageStartEvents as startEvents,
transformedDurationData, transformedDurationData,
transformedDurationMedianData,
flattenedDurationData, flattenedDurationData,
durationChartPlottableData, durationChartPlottableData,
durationChartPlottableMedianData,
startDate, startDate,
endDate, endDate,
issueStage, issueStage,
...@@ -165,6 +168,18 @@ describe('Cycle analytics utils', () => { ...@@ -165,6 +168,18 @@ describe('Cycle analytics utils', () => {
}); });
}); });
describe('getDurationChartMedianData', () => {
it('computes the plottable data as expected', () => {
const plottableData = getDurationChartMedianData(
transformedDurationMedianData,
startDate,
endDate,
);
expect(plottableData).toStrictEqual(durationChartPlottableMedianData);
});
});
describe('transformRawStages', () => { describe('transformRawStages', () => {
it('retains all the stage properties', () => { it('retains all the stage properties', () => {
const transformed = transformRawStages([issueStage, rawCustomStage]); const transformed = transformRawStages([issueStage, rawCustomStage]);
......
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