summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/lib/utils/chart_utils.js83
-rw-r--r--app/assets/javascripts/pages/projects/graphs/charts/index.js73
-rw-r--r--app/assets/javascripts/pages/projects/pipelines/charts/index.js81
-rw-r--r--app/views/projects/graphs/charts.html.haml12
-rw-r--r--app/views/projects/pipelines/charts/_pipeline_times.haml6
-rw-r--r--app/views/projects/pipelines/charts/_pipelines.haml9
-rw-r--r--package.json2
-rw-r--r--yarn.lock41
8 files changed, 219 insertions, 88 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" }
diff --git a/package.json b/package.json
index 7110baef8b3..c88ade87af6 100644
--- a/package.json
+++ b/package.json
@@ -38,7 +38,7 @@
"bootstrap": "4.1.3",
"brace-expansion": "^1.1.8",
"cache-loader": "^2.0.1",
- "chart.js": "1.0.2",
+ "chart.js": "2.7.2",
"classlist-polyfill": "^1.2.0",
"clipboard": "^1.7.1",
"codesandbox-api": "^0.0.20",
diff --git a/yarn.lock b/yarn.lock
index 9d0ba6640f0..8bff9c59113 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2122,10 +2122,28 @@ chardet@^0.5.0:
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
-chart.js@1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-1.0.2.tgz#ad57d2229cfd8ccf5955147e8121b4911e69dfe7"
- integrity sha1-rVfSIpz9jM9ZVRR+gSG0kR5p3+c=
+chart.js@2.7.2:
+ version "2.7.2"
+ resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.7.2.tgz#3c9fde4dc5b95608211bdefeda7e5d33dffa5714"
+ integrity sha512-90wl3V9xRZ8tnMvMlpcW+0Yg13BelsGS9P9t0ClaDxv/hdypHDr/YAGf+728m11P5ljwyB0ZHfPKCapZFqSqYA==
+ dependencies:
+ chartjs-color "^2.1.0"
+ moment "^2.10.2"
+
+chartjs-color-string@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.5.0.tgz#8d3752d8581d86687c35bfe2cb80ac5213ceb8c1"
+ integrity sha512-amWNvCOXlOUYxZVDSa0YOab5K/lmEhbFNKI55PWc4mlv28BDzA7zaoQTGxSBgJMHIW+hGX8YUrvw/FH4LyhwSQ==
+ dependencies:
+ color-name "^1.0.0"
+
+chartjs-color@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.2.0.tgz#84a2fb755787ed85c39dd6dd8c7b1d88429baeae"
+ integrity sha1-hKL7dVeH7YXDndbdjHsdiEKbrq4=
+ dependencies:
+ chartjs-color-string "^0.5.0"
+ color-convert "^0.5.3"
check-types@^7.3.0:
version "7.3.0"
@@ -2296,6 +2314,11 @@ collection-visit@^1.0.0:
map-visit "^1.0.0"
object-visit "^1.0.0"
+color-convert@^0.5.3:
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd"
+ integrity sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=
+
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -2303,7 +2326,7 @@ color-convert@^1.9.0:
dependencies:
color-name "1.1.3"
-color-name@1.1.3:
+color-name@1.1.3, color-name@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
@@ -6985,10 +7008,10 @@ mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
dependencies:
minimist "0.0.8"
-moment@2.x, moment@^2.21.0:
- version "2.22.2"
- resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
- integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=
+moment@2.x, moment@^2.10.2, moment@^2.21.0:
+ version "2.23.0"
+ resolved "https://registry.yarnpkg.com/moment/-/moment-2.23.0.tgz#759ea491ac97d54bac5ad776996e2a58cc1bc225"
+ integrity sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA==
monaco-editor-webpack-plugin@^1.7.0:
version "1.7.0"