Commit f2ff804f authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Minor clean up and jsDocs

Adds jsDoc blocks to some of the functions
for preparing the chart data
parent 789d9719
......@@ -26,7 +26,6 @@ export default {
return this.chartData && this.chartData.data && this.chartData.data.length;
},
selectedFiltersText() {
// TODO: I think we should show labels that have 0 data, currently doesnt appear
const { subject, selectedLabelIds } = this.filters;
return sprintf(
s__('CycleAnalyticsCharts|Showing %{subject} and %{selectedLabelsCount} labels'),
......@@ -71,18 +70,10 @@ export default {
<div class="row">
<div class="col-12">
<h3>{{ __('Type of work') }}</h3>
<p v-if="hasData">
{{ summaryDescription }}
</p>
</div>
</div>
<div v-if="hasData" class="row">
<div class="col-12">
<header>
<div v-if="hasData">
<p>{{ summaryDescription }}</p>
<h4>{{ __('Tasks by type') }}</h4>
<p>{{ selectedFiltersText }}</p>
</header>
<section>
<gl-stacked-column-chart
:option="$options.chartOptions"
:data="chartData.data"
......@@ -92,12 +83,8 @@ export default {
y-axis-title="Number of tasks"
:series-names="chartData.seriesNames"
/>
</section>
</div>
</div>
<div v-else class="row">
<div class="col-12">
<div class="bs-callout bs-callout-info">
</div>
<div v-else class="bs-callout bs-callout-info">
<p>{{ __('There is no data available. Please change your selection.') }}</p>
</div>
</div>
......
......@@ -27,7 +27,6 @@ export const durationChartPlottableData = state => {
};
export const tasksByTypeChartData = ({ tasksByType, startDate, endDate }) => {
// TODO: remove this check, return empty data if need be
if (tasksByType && tasksByType.data.length) {
return getTasksByTypeData({
data: tasksByType.data,
......
......@@ -78,18 +78,9 @@ export const transformRawStages = (stages = []) =>
name: name.length ? name : title,
}));
// converts the series data into key value pairs
export const transformRawTasksByTypeData = (data = []) => {
if (!data.length) return [];
return data.map(({ series, ...rest }) =>
convertObjectPropsToCamelCase(
{
...rest,
series: Object.fromEntries(series),
},
{ deep: true },
),
);
return data.map(d => convertObjectPropsToCamelCase(d, { deep: true }));
};
export const nestQueryStringKeys = (obj = null, targetKey = '') => {
......@@ -205,24 +196,45 @@ export const getDurationChartData = (data, startDate, endDate) => {
return eventData;
};
const toUnix = datetime => new Date(datetime).getTime();
export const orderByDate = (a, b) => toUnix(a) - toUnix(b);
// TODO: code blocks + specs
// The api only returns datapoints with a value, 0 values are ignored
// overwrites the default values with any value that was returned from the api
const zeroMissingDataPoints = ({ data, defaultData }) => ({ ...defaultData, ...data });
export const orderByDate = (a, b, dateFmt = datetime => new Date(datetime).getTime()) =>
dateFmt(a) - dateFmt(b);
// TODO: docblocks
// Array of values [date, value]
// ignore the date, just return the value, default sort by ascending date
/**
* Takes a dictionary of dates and the associated value, sorts them and returns just the value
*
* @param {Object.<Date, number>} series - Key value pair of dates and the value for that date
* @returns {number[]} The values of each key value pair
*/
export const flattenTaskByTypeSeries = (series = {}) =>
Object.entries(series)
.sort((a, b) => orderByDate(a[0], b[0]))
.map(dataSet => dataSet[1]);
// TODO: docblocks
// GROSS
/**
* @typedef {Object} RawTasksByTypeData
* @property {Object} label - Raw data for a group label
* @property {Array} series - Array of arrays with date and associated value ie [ ['2020-01-01', 10],['2020-01-02', 10] ]
* @typedef {Object} TransformedTasksByTypeData
* @property {Array} groupBy - The list of dates for the range of data in each data series
* @property {Array} data - An array of the data values for each series
* @property {Array} seriesNames - Names of the series to be charted ie label names
*/
/**
* Takes the raw tasks by type data and generates an array of data points,
* an array of data series and an array of data labels for the given time period.
*
* Currently the data is transformed to support use in a stacked column chart:
* https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/charts-stacked-column-chart--stacked
*
* @param {Object} obj
* @param {RawTasksByTypeData[]} obj.data - array of raw data, each element contains a label and series
* @param {Date} obj.startDate - start date in ISO date format
* @param {Date} obj.endDate - end date in ISO date format
*
* @returns {TransformedTasksByTypeData} The transformed data ready for use in charts
*/
export const getTasksByTypeData = ({ data = [], startDate = null, endDate = null }) => {
if (!startDate || !endDate || !data.length) {
return {
......@@ -251,7 +263,7 @@ export const getTasksByTypeData = ({ data = [], startDate = null, endDate = null
acc.data = [
...acc.data,
// adds 0 values for each data point and overrides with data from the series
flattenTaskByTypeSeries({ ...zeroValuesForEachDataPoint, ...series }),
flattenTaskByTypeSeries({ ...zeroValuesForEachDataPoint, ...Object.fromEntries(series) }),
];
return acc;
},
......
......@@ -5,11 +5,6 @@ exports[`TasksByTypeChart no data available should render the no data available
<div class=\\"row\\">
<div class=\\"col-12\\">
<h3>Type of work</h3>
<!---->
</div>
</div>
<div class=\\"row\\">
<div class=\\"col-12\\">
<div class=\\"bs-callout bs-callout-info\\">
<p>There is no data available. Please change your selection.</p>
</div>
......@@ -23,20 +18,12 @@ exports[`TasksByTypeChart with data available should render the loading chart 1`
<div class=\\"row\\">
<div class=\\"col-12\\">
<h3>Type of work</h3>
<p>
Showing data for group 'Gitlab Org' from Dec 11, 2019 to Jan 10, 2020
</p>
</div>
</div>
<div class=\\"row\\">
<div class=\\"col-12\\">
<header>
<div>
<p>Showing data for group 'Gitlab Org' from Dec 11, 2019 to Jan 10, 2020</p>
<h4>Tasks by type</h4>
<p>Showing Issue and 3 labels</p>
</header>
<section>
<gl-stacked-column-chart-stub data=\\"0,1,2,5,2,3,2,4,1\\" option=\\"[object Object]\\" presentation=\\"stacked\\" groupby=\\"Group 1,Group 2,Group 3\\" xaxistype=\\"category\\" xaxistitle=\\"Date\\" yaxistitle=\\"Number of tasks\\" seriesnames=\\"Cool label,Normal label\\" legendaveragetext=\\"Avg\\" legendmaxtext=\\"Max\\"></gl-stacked-column-chart-stub>
</section>
</div>
</div>
</div>
</div>"
......
......@@ -2,7 +2,6 @@ import { shallowMount } from '@vue/test-utils';
import TasksByTypeChart from 'ee/analytics/cycle_analytics/components/tasks_by_type_chart.vue';
import { TASKS_BY_TYPE_SUBJECT_ISSUE } from 'ee/analytics/cycle_analytics/constants';
// TODO: maybe move to mock data
const seriesNames = ['Cool label', 'Normal label'];
const data = [[0, 1, 2], [5, 2, 3], [2, 4, 1]];
const groupBy = ['Group 1', 'Group 2', 'Group 3'];
......
......@@ -248,7 +248,10 @@ describe('Cycle analytics utils', () => {
let transformed = {};
const groupBy = getDatesInRange(startDate, endDate, toYmd);
const data = transformedTasksByTypeData.map(({ series }) => Object.values(series));
// only return the values, drop the date which is the first paramater
const extractSeriesValues = ({ series }) => series.map(kv => kv[1]);
const data = transformedTasksByTypeData.map(extractSeriesValues);
const labels = transformedTasksByTypeData.map(d => {
const { label } = d;
return label.title;
......
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