Commit 12ae5547 authored by Simon Knox's avatar Simon Knox Committed by Illya Klymov

Better axis labels for burndown charts

Also for burnup charts.
1. Set min of 1 day (as that is our bucket size)
1. Set min of 1 on the y-axis
1. Format dates in a more human-friendly way
1. Remove avg/max from chart legend
parent adc7dbeb
<script> <script>
import { merge } from 'lodash';
import { GlLineChart } from '@gitlab/ui/dist/charts'; import { GlLineChart } from '@gitlab/ui/dist/charts';
import dateFormat from 'dateformat'; import dateFormat from 'dateformat';
import ResizableChartContainer from '~/vue_shared/components/resizable_chart/resizable_chart_container.vue'; import ResizableChartContainer from '~/vue_shared/components/resizable_chart/resizable_chart_container.vue';
import { s__, __, sprintf } from '~/locale'; import { s__, __, sprintf } from '~/locale';
import commonChartOptions from './common_chart_options';
export default { export default {
components: { components: {
...@@ -87,30 +89,15 @@ export default { ...@@ -87,30 +89,15 @@ export default {
return series; return series;
}, },
options() { options() {
return { return merge({}, commonChartOptions, {
xAxis: { xAxis: {
name: '',
type: 'time',
min: this.startDate, min: this.startDate,
max: this.dueDate, max: this.dueDate,
axisLine: {
show: true,
},
}, },
yAxis: { yAxis: {
name: this.issuesSelected ? __('Total issues') : __('Total weight'), name: this.issuesSelected ? __('Total issues') : __('Total weight'),
axisLine: {
show: true,
},
splitLine: {
show: false,
},
},
tooltip: {
trigger: 'item',
formatter: () => '',
}, },
}; });
}, },
}, },
methods: { methods: {
...@@ -150,6 +137,7 @@ export default { ...@@ -150,6 +137,7 @@ export default {
:data="dataSeries" :data="dataSeries"
:option="options" :option="options"
:format-tooltip-text="formatTooltipText" :format-tooltip-text="formatTooltipText"
:include-legend-avg-max="false"
> >
<template slot="tooltipTitle">{{ tooltip.title }}</template> <template slot="tooltipTitle">{{ tooltip.title }}</template>
<template slot="tooltipContent">{{ tooltip.content }}</template> <template slot="tooltipContent">{{ tooltip.content }}</template>
......
<script> <script>
import { merge } from 'lodash';
import { GlLineChart } from '@gitlab/ui/dist/charts'; import { GlLineChart } from '@gitlab/ui/dist/charts';
import dateFormat from 'dateformat'; import dateFormat from 'dateformat';
import ResizableChartContainer from '~/vue_shared/components/resizable_chart/resizable_chart_container.vue'; import ResizableChartContainer from '~/vue_shared/components/resizable_chart/resizable_chart_container.vue';
import { __, sprintf } from '~/locale'; import { __, sprintf } from '~/locale';
import commonChartOptions from './common_chart_options';
export default { export default {
components: { components: {
...@@ -44,30 +46,15 @@ export default { ...@@ -44,30 +46,15 @@ export default {
return series; return series;
}, },
options() { options() {
return { return merge({}, commonChartOptions, {
xAxis: { xAxis: {
name: '',
type: 'time',
min: this.startDate, min: this.startDate,
max: this.dueDate, max: this.dueDate,
axisLine: {
show: true,
},
}, },
yAxis: { yAxis: {
name: __('Total issues'), name: __('Total issues'),
axisLine: {
show: true,
},
splitLine: {
show: false,
},
}, },
tooltip: { });
trigger: 'item',
formatter: () => '',
},
};
}, },
}, },
methods: { methods: {
...@@ -91,7 +78,12 @@ export default { ...@@ -91,7 +78,12 @@ export default {
<h3>{{ __('Burnup chart') }}</h3> <h3>{{ __('Burnup chart') }}</h3>
</div> </div>
<resizable-chart-container class="js-burnup-chart"> <resizable-chart-container class="js-burnup-chart">
<gl-line-chart :data="dataSeries" :option="options" :format-tooltip-text="formatTooltipText"> <gl-line-chart
:data="dataSeries"
:option="options"
:format-tooltip-text="formatTooltipText"
:include-legend-avg-max="false"
>
<template slot="tooltipTitle">{{ tooltip.title }}</template> <template slot="tooltipTitle">{{ tooltip.title }}</template>
<template slot="tooltipContent">{{ tooltip.content }}</template> <template slot="tooltipContent">{{ tooltip.content }}</template>
</gl-line-chart> </gl-line-chart>
......
import dateFormat from 'dateformat';
const msInOneDay = 60 * 60 * 24 * 1000;
export default {
grid: {
// TODO: containLabel doesn't currently work, so we also need to add grid
// https://github.com/apache/incubator-echarts/issues/11773
containLabel: true,
top: 16,
bottom: 16,
left: 48,
right: 48,
},
xAxis: {
name: '',
type: 'time',
minInterval: msInOneDay,
axisLabel: {
formatter(value) {
return dateFormat(value, 'dd mmm yyyy');
},
},
axisLine: {
show: true,
},
axisPointer: {
snap: true,
},
},
yAxis: {
axisLine: {
show: true,
},
splitLine: {
show: false,
},
minInterval: 1,
},
tooltip: {
trigger: 'item',
formatter: () => '',
},
};
---
title: Better burndown chart axis formatting
merge_request: 38113
author:
type: added
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlLineChart } from '@gitlab/ui/dist/charts';
import BurndownChart from 'ee/burndown_chart/components/burndown_chart.vue'; import BurndownChart from 'ee/burndown_chart/components/burndown_chart.vue';
import ResizableChartContainer from '~/vue_shared/components/resizable_chart/resizable_chart_container.vue';
describe('burndown_chart', () => { describe('burndown_chart', () => {
let wrapper; let wrapper;
...@@ -11,12 +13,17 @@ describe('burndown_chart', () => { ...@@ -11,12 +13,17 @@ describe('burndown_chart', () => {
openIssuesWeight: [], openIssuesWeight: [],
}; };
const findChart = () => wrapper.find(GlLineChart);
const createComponent = (props = {}) => { const createComponent = (props = {}) => {
wrapper = shallowMount(BurndownChart, { wrapper = shallowMount(BurndownChart, {
propsData: { propsData: {
...defaultProps, ...defaultProps,
...props, ...props,
}, },
stubs: {
ResizableChartContainer,
},
}); });
}; };
...@@ -33,7 +40,7 @@ describe('burndown_chart', () => { ...@@ -33,7 +40,7 @@ describe('burndown_chart', () => {
}); });
describe('with multiple points', () => { describe('with multiple points', () => {
it('shows guideline', () => { beforeEach(() => {
createComponent({ createComponent({
openIssuesCount: [ openIssuesCount: [
{ '2019-08-07T00:00:00.000Z': 100 }, { '2019-08-07T00:00:00.000Z': 100 },
...@@ -41,10 +48,29 @@ describe('burndown_chart', () => { ...@@ -41,10 +48,29 @@ describe('burndown_chart', () => {
{ '2019-09-08T00:00:00.000Z': 1 }, { '2019-09-08T00:00:00.000Z': 1 },
], ],
}); });
});
it('shows guideline', () => {
const data = wrapper.vm.dataSeries; const data = wrapper.vm.dataSeries;
expect(data).toHaveLength(2); expect(data).toHaveLength(2);
expect(data[1].name).toBe('Guideline'); expect(data[1].name).toBe('Guideline');
}); });
it('only shows integers on axis labels', () => {
const msInOneDay = 60 * 60 * 24 * 1000;
expect(findChart().props('option')).toMatchObject({
xAxis: {
type: 'time',
minInterval: msInOneDay,
},
yAxis: {
minInterval: 1,
},
});
});
it('does not show average or max values in legend', () => {
expect(findChart().props('includeLegendAvgMax')).toBe(false);
});
}); });
}); });
...@@ -11,6 +11,8 @@ describe('Burnup chart', () => { ...@@ -11,6 +11,8 @@ describe('Burnup chart', () => {
dueDate: '2019-09-09T00:00:00.000Z', dueDate: '2019-09-09T00:00:00.000Z',
}; };
const findChart = () => wrapper.find(GlLineChart);
const createComponent = (props = {}) => { const createComponent = (props = {}) => {
wrapper = shallowMount(BurnupChart, { wrapper = shallowMount(BurnupChart, {
propsData: { propsData: {
...@@ -29,7 +31,7 @@ describe('Burnup chart', () => { ...@@ -29,7 +31,7 @@ describe('Burnup chart', () => {
${[{ '2019-08-07T00:00:00.000Z': 100 }, { '2019-08-08T00:00:00.000Z': 99 }, { '2019-09-08T00:00:00.000Z': 1 }]} ${[{ '2019-08-07T00:00:00.000Z': 100 }, { '2019-08-08T00:00:00.000Z': 99 }, { '2019-09-08T00:00:00.000Z': 1 }]}
`('renders the lineChart correctly', ({ scope }) => { `('renders the lineChart correctly', ({ scope }) => {
createComponent({ scope }); createComponent({ scope });
const chartData = wrapper.find(GlLineChart).props('data'); const chartData = findChart().props('data');
expect(chartData).toEqual([ expect(chartData).toEqual([
{ {
...@@ -38,4 +40,21 @@ describe('Burnup chart', () => { ...@@ -38,4 +40,21 @@ describe('Burnup chart', () => {
}, },
]); ]);
}); });
it('only shows integers on axis labels', () => {
const msInOneDay = 60 * 60 * 24 * 1000;
expect(findChart().props('option')).toMatchObject({
xAxis: {
type: 'time',
minInterval: msInOneDay,
},
yAxis: {
minInterval: 1,
},
});
});
it('does not show average or max values in legend', () => {
expect(findChart().props('includeLegendAvgMax')).toBe(false);
});
}); });
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