diff options
Diffstat (limited to 'app')
6 files changed, 186 insertions, 78 deletions
diff --git a/app/assets/javascripts/lib/utils/chart_utils.js b/app/assets/javascripts/lib/utils/chart_utils.js new file mode 100644 index 00000000000..0f78756aac8 --- /dev/null +++ b/app/assets/javascripts/lib/utils/chart_utils.js @@ -0,0 +1,83 @@ +const commonTooltips = () => ({ + mode: 'x', + intersect: false, +}); + +const adjustedFontScale = () => ({ + fontSize: 8, +}); + +const yAxesConfig = (shouldAdjustFontSize = false) => ({ + yAxes: [ + { + ticks: { + beginAtZero: true, + ...(shouldAdjustFontSize ? adjustedFontScale() : {}), + }, + }, + ], +}); + +const xAxesConfig = (shouldAdjustFontSize = false) => ({ + xAxes: [ + { + ticks: { + ...(shouldAdjustFontSize ? adjustedFontScale() : {}), + }, + }, + ], +}); + +const commonChartOptions = () => ({ + responsive: true, + maintainAspectRatio: false, + legend: false, +}); + +export const barChartOptions = shouldAdjustFontSize => ({ + ...commonChartOptions(), + scales: { + ...yAxesConfig(shouldAdjustFontSize), + ...xAxesConfig(shouldAdjustFontSize), + }, + tooltips: { + ...commonTooltips(), + displayColors: false, + callbacks: { + title() { + return ''; + }, + label({ xLabel, yLabel }) { + return `${xLabel}: ${yLabel}`; + }, + }, + }, +}); + +export const pieChartOptions = commonChartOptions; + +export const lineChartOptions = ({ width, numberOfPoints, shouldAdjustFontSize }) => ({ + ...commonChartOptions(), + scales: { + ...yAxesConfig(shouldAdjustFontSize), + ...xAxesConfig(shouldAdjustFontSize), + }, + elements: { + point: { + hitRadius: width / (numberOfPoints * 2), + }, + }, + tooltips: { + ...commonTooltips(), + caretSize: 0, + multiKeyBackground: 'rgba(0,0,0,0)', + callbacks: { + labelColor({ datasetIndex }, { config }) { + return { + backgroundColor: config.data.datasets[datasetIndex].backgroundColor, + borderColor: 'rgba(0,0,0,0)', + }; + }, + }, + }, +}); diff --git a/app/assets/javascripts/pages/projects/graphs/charts/index.js b/app/assets/javascripts/pages/projects/graphs/charts/index.js index 26d7fa7371d..314519ee442 100644 --- a/app/assets/javascripts/pages/projects/graphs/charts/index.js +++ b/app/assets/javascripts/pages/projects/graphs/charts/index.js @@ -2,42 +2,44 @@ import $ from 'jquery'; import Chart from 'chart.js'; import _ from 'underscore'; +import { barChartOptions, pieChartOptions } from '~/lib/utils/chart_utils'; + document.addEventListener('DOMContentLoaded', () => { const projectChartData = JSON.parse(document.getElementById('projectChartData').innerHTML); - const responsiveChart = (selector, data) => { - const options = { - scaleOverlay: true, - responsive: true, - pointHitDetectionRadius: 2, - maintainAspectRatio: false, - }; + const barChart = (selector, data) => { // get selector by context const ctx = selector.get(0).getContext('2d'); // pointing parent container to make chart.js inherit its width const container = $(selector).parent(); - const generateChart = () => { - selector.attr('width', $(container).width()); - if (window.innerWidth < 768) { - // Scale fonts if window width lower than 768px (iPad portrait) - options.scaleFontSize = 8; - } - return new Chart(ctx).Bar(data, options); - }; - // enabling auto-resizing - $(window).resize(generateChart); - return generateChart(); + selector.attr('width', $(container).width()); + + // Scale fonts if window width lower than 768px (iPad portrait) + const shouldAdjustFontSize = window.innerWidth < 768; + return new Chart(ctx, { + type: 'bar', + data, + options: barChartOptions(shouldAdjustFontSize), + }); + }; + + const pieChart = (context, data) => { + const options = pieChartOptions(); + + return new Chart(context, { + type: 'pie', + data, + options, + }); }; const chartData = data => ({ labels: Object.keys(data), datasets: [ { - fillColor: 'rgba(220,220,220,0.5)', - strokeColor: 'rgba(220,220,220,1)', - barStrokeWidth: 1, - barValueSpacing: 1, - barDatasetSpacing: 1, + backgroundColor: 'rgba(220,220,220,0.5)', + borderColor: 'rgba(220,220,220,1)', + borderWidth: 1, data: _.values(data), }, ], @@ -59,24 +61,27 @@ document.addEventListener('DOMContentLoaded', () => { }; const hourData = chartData(projectChartData.hour); - responsiveChart($('#hour-chart'), hourData); + barChart($('#hour-chart'), hourData); const weekDays = reorderWeekDays(projectChartData.weekDays, gon.first_day_of_week); const dayData = chartData(weekDays); - responsiveChart($('#weekday-chart'), dayData); + barChart($('#weekday-chart'), dayData); const monthData = chartData(projectChartData.month); - responsiveChart($('#month-chart'), monthData); + barChart($('#month-chart'), monthData); - const data = projectChartData.languages; + const data = { + datasets: [ + { + data: projectChartData.languages.map(x => x.value), + backgroundColor: projectChartData.languages.map(x => x.color), + hoverBackgroundColor: projectChartData.languages.map(x => x.highlight), + }, + ], + labels: projectChartData.languages.map(x => x.label), + }; const ctx = $('#languages-chart') .get(0) .getContext('2d'); - const options = { - scaleOverlay: true, - responsive: true, - maintainAspectRatio: false, - }; - - new Chart(ctx).Pie(data, options); + pieChart(ctx, data); }); diff --git a/app/assets/javascripts/pages/projects/pipelines/charts/index.js b/app/assets/javascripts/pages/projects/pipelines/charts/index.js index 48353f3b4ef..9fa580d2ba9 100644 --- a/app/assets/javascripts/pages/projects/pipelines/charts/index.js +++ b/app/assets/javascripts/pages/projects/pipelines/charts/index.js @@ -1,29 +1,31 @@ import $ from 'jquery'; import Chart from 'chart.js'; -const options = { - scaleOverlay: true, - responsive: true, - maintainAspectRatio: false, -}; +import { barChartOptions, lineChartOptions } from '~/lib/utils/chart_utils'; + +const SUCCESS_LINE_COLOR = '#1aaa55'; + +const TOTAL_LINE_COLOR = '#707070'; -const buildChart = chartScope => { +const buildChart = (chartScope, shouldAdjustFontSize) => { const data = { labels: chartScope.labels, datasets: [ { - fillColor: '#707070', - strokeColor: '#707070', - pointColor: '#707070', - pointStrokeColor: '#EEE', - data: chartScope.totalValues, + backgroundColor: SUCCESS_LINE_COLOR, + borderColor: SUCCESS_LINE_COLOR, + pointBackgroundColor: SUCCESS_LINE_COLOR, + pointBorderColor: '#fff', + data: chartScope.successValues, + fill: 'origin', }, { - fillColor: '#1aaa55', - strokeColor: '#1aaa55', - pointColor: '#1aaa55', - pointStrokeColor: '#fff', - data: chartScope.successValues, + backgroundColor: TOTAL_LINE_COLOR, + borderColor: TOTAL_LINE_COLOR, + pointBackgroundColor: TOTAL_LINE_COLOR, + pointBorderColor: '#EEE', + data: chartScope.totalValues, + fill: '-1', }, ], }; @@ -31,36 +33,51 @@ const buildChart = chartScope => { .get(0) .getContext('2d'); - new Chart(ctx).Line(data, options); + return new Chart(ctx, { + type: 'line', + data, + options: lineChartOptions({ + width: ctx.canvas.width, + numberOfPoints: chartScope.totalValues.length, + shouldAdjustFontSize, + }), + }); }; -document.addEventListener('DOMContentLoaded', () => { - const chartTimesData = JSON.parse(document.getElementById('pipelinesTimesChartsData').innerHTML); - const chartsData = JSON.parse(document.getElementById('pipelinesChartsData').innerHTML); +const buildBarChart = (chartTimesData, shouldAdjustFontSize) => { const data = { labels: chartTimesData.labels, datasets: [ { - fillColor: 'rgba(220,220,220,0.5)', - strokeColor: 'rgba(220,220,220,1)', - barStrokeWidth: 1, + backgroundColor: 'rgba(220,220,220,0.5)', + borderColor: 'rgba(220,220,220,1)', + borderWidth: 1, barValueSpacing: 1, barDatasetSpacing: 1, data: chartTimesData.values, }, ], }; - - if (window.innerWidth < 768) { - // Scale fonts if window width lower than 768px (iPad portrait) - options.scaleFontSize = 8; - } - - new Chart( + return new Chart( $('#build_timesChart') .get(0) .getContext('2d'), - ).Bar(data, options); + { + type: 'bar', + data, + options: barChartOptions(shouldAdjustFontSize), + }, + ); +}; + +document.addEventListener('DOMContentLoaded', () => { + const chartTimesData = JSON.parse(document.getElementById('pipelinesTimesChartsData').innerHTML); + const chartsData = JSON.parse(document.getElementById('pipelinesChartsData').innerHTML); + + // Scale fonts if window width lower than 768px (iPad portrait) + const shouldAdjustFontSize = window.innerWidth < 768; + + buildBarChart(chartTimesData, shouldAdjustFontSize); - chartsData.forEach(scope => buildChart(scope)); + chartsData.forEach(scope => buildChart(scope, shouldAdjustFontSize)); }); diff --git a/app/views/projects/graphs/charts.html.haml b/app/views/projects/graphs/charts.html.haml index b0e22a35fe1..60160f521ad 100644 --- a/app/views/projects/graphs/charts.html.haml +++ b/app/views/projects/graphs/charts.html.haml @@ -55,23 +55,23 @@ #{@commits_graph.authors} = (_("Authors: %{authors}") % { authors: "<strong>#{authors}</strong>" }).html_safe .col-md-6 + %p.slead + = _("Commits per day of month") %div - %p.slead - = _("Commits per day of month") %canvas#month-chart .row .col-md-6 .col-md-6 + %p.slead + = _("Commits per weekday") %div - %p.slead - = _("Commits per weekday") %canvas#weekday-chart .row .col-md-6 .col-md-6 + %p.slead + = _("Commits per day hour (UTC)") %div - %p.slead - = _("Commits per day hour (UTC)") %canvas#hour-chart -# haml-lint:disable InlineJavaScript diff --git a/app/views/projects/pipelines/charts/_pipeline_times.haml b/app/views/projects/pipelines/charts/_pipeline_times.haml index c23fe6ff170..c0ac79ed5f8 100644 --- a/app/views/projects/pipelines/charts/_pipeline_times.haml +++ b/app/views/projects/pipelines/charts/_pipeline_times.haml @@ -1,7 +1,7 @@ -%div - %p.light - = _("Commit duration in minutes for last 30 commits") +%p.light + = _("Commit duration in minutes for last 30 commits") +%div %canvas#build_timesChart{ height: 200 } -# haml-lint:disable InlineJavaScript diff --git a/app/views/projects/pipelines/charts/_pipelines.haml b/app/views/projects/pipelines/charts/_pipelines.haml index 14b3d47a9c2..47f1f074210 100644 --- a/app/views/projects/pipelines/charts/_pipelines.haml +++ b/app/views/projects/pipelines/charts/_pipelines.haml @@ -13,18 +13,21 @@ %p.light = _("Pipelines for last week") (#{date_from_to(Date.today - 7.days, Date.today)}) - %canvas#weekChart{ height: 200 } + %div + %canvas#weekChart{ height: 200 } .prepend-top-default %p.light = _("Pipelines for last month") (#{date_from_to(Date.today - 30.days, Date.today)}) - %canvas#monthChart{ height: 200 } + %div + %canvas#monthChart{ height: 200 } .prepend-top-default %p.light = _("Pipelines for last year") - %canvas#yearChart.padded{ height: 250 } + %div + %canvas#yearChart.padded{ height: 250 } -# haml-lint:disable InlineJavaScript %script#pipelinesChartsData{ type: "application/json" } |