Commit 4fbec2c1 authored by Martin Wortschack's avatar Martin Wortschack

Migrate repository charts

- Migrates charts to gitlab-ui charts
and replaces pie chart with column chart
parent c7d27481
import $ from 'jquery'; import Vue from 'vue';
import Chart from 'chart.js'; import { __ } from '~/locale';
import { barChartOptions, pieChartOptions } from '~/lib/utils/chart_utils'; import { GlColumnChart } from '@gitlab/ui/dist/charts';
import SeriesDataMixin from './series_data_mixin';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const projectChartData = JSON.parse(document.getElementById('projectChartData').innerHTML); const languagesContainer = document.getElementById('js-languages-chart');
const monthContainer = document.getElementById('js-month-chart');
const weekdayContainer = document.getElementById('js-weekday-chart');
const hourContainer = document.getElementById('js-hour-chart');
const barChart = (selector, data) => { const LANGUAGE_CHART_HEIGHT = 300;
// 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();
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: [
{
backgroundColor: 'rgba(220,220,220,0.5)',
borderColor: 'rgba(220,220,220,1)',
borderWidth: 1,
data: Object.values(data),
},
],
});
const reorderWeekDays = (weekDays, firstDayOfWeek = 0) => { const reorderWeekDays = (weekDays, firstDayOfWeek = 0) => {
if (firstDayOfWeek === 0) { if (firstDayOfWeek === 0) {
...@@ -58,28 +26,115 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -58,28 +26,115 @@ document.addEventListener('DOMContentLoaded', () => {
}, {}); }, {});
}; };
const hourData = chartData(projectChartData.hour); // eslint-disable-next-line no-new
barChart($('#hour-chart'), hourData); new Vue({
el: languagesContainer,
const weekDays = reorderWeekDays(projectChartData.weekDays, gon.first_day_of_week); components: {
const dayData = chartData(weekDays); GlColumnChart,
barChart($('#weekday-chart'), dayData); },
data() {
return {
chartData: JSON.parse(languagesContainer.dataset.chartData),
};
},
computed: {
seriesData() {
return { full: this.chartData.map(d => [d.label, d.value]) };
},
},
render(h) {
return h(GlColumnChart, {
props: {
data: this.seriesData,
xAxisTitle: __('Used programming language'),
yAxisTitle: __('Percentage'),
xAxisType: 'category',
},
attrs: {
height: LANGUAGE_CHART_HEIGHT,
},
});
},
});
const monthData = chartData(projectChartData.month); // eslint-disable-next-line no-new
barChart($('#month-chart'), monthData); new Vue({
el: monthContainer,
components: {
GlColumnChart,
},
mixins: [SeriesDataMixin],
data() {
return {
chartData: JSON.parse(monthContainer.dataset.chartData),
};
},
render(h) {
return h(GlColumnChart, {
props: {
data: this.seriesData,
xAxisTitle: __('Day of month'),
yAxisTitle: __('No. of commits'),
xAxisType: 'category',
},
});
},
});
const data = { // eslint-disable-next-line no-new
datasets: [ new Vue({
{ el: weekdayContainer,
data: projectChartData.languages.map(x => x.value), components: {
backgroundColor: projectChartData.languages.map(x => x.color), GlColumnChart,
hoverBackgroundColor: projectChartData.languages.map(x => x.highlight), },
data() {
return {
chartData: JSON.parse(weekdayContainer.dataset.chartData),
};
},
computed: {
seriesData() {
const weekDays = reorderWeekDays(this.chartData, gon.first_day_of_week);
const data = Object.keys(weekDays).reduce((acc, key) => {
acc.push([key, weekDays[key]]);
return acc;
}, []);
return { full: data };
}, },
], },
labels: projectChartData.languages.map(x => x.label), render(h) {
}; return h(GlColumnChart, {
const ctx = $('#languages-chart') props: {
.get(0) data: this.seriesData,
.getContext('2d'); xAxisTitle: __('Weekday'),
pieChart(ctx, data); yAxisTitle: __('No. of commits'),
xAxisType: 'category',
},
});
},
});
// eslint-disable-next-line no-new
new Vue({
el: hourContainer,
components: {
GlColumnChart,
},
mixins: [SeriesDataMixin],
data() {
return {
chartData: JSON.parse(hourContainer.dataset.chartData),
};
},
render(h) {
return h(GlColumnChart, {
props: {
data: this.seriesData,
xAxisTitle: __('Hour (UTC)'),
yAxisTitle: __('No. of commits'),
xAxisType: 'category',
},
});
},
});
}); });
export default {
computed: {
seriesData() {
const data = Object.keys(this.chartData).reduce((acc, key) => {
acc.push([key, this.chartData[key]]);
return acc;
}, []);
return { full: data };
},
},
};
...@@ -7,20 +7,7 @@ ...@@ -7,20 +7,7 @@
%p %p
= _("Measured in bytes of code. Excludes generated and vendored code.") = _("Measured in bytes of code. Excludes generated and vendored code.")
.row #js-languages-chart{ data: { chart_data: @languages.to_json.html_safe } }
.col-md-4
%ul.bordered-list
- @languages.each do |language|
%li
%span{ style: "color: #{language[:color]}" }
= icon('circle')
&nbsp;
= language[:label]
.float-right
= language[:value]
\%
.col-md-8
%canvas#languages-chart{ height: 400 }
.repo-charts .repo-charts
.sub-header-block.border-top .sub-header-block.border-top
...@@ -60,27 +47,18 @@ ...@@ -60,27 +47,18 @@
%p.slead %p.slead
= _("Commits per day of month") = _("Commits per day of month")
%div %div
%canvas#month-chart #js-month-chart{ data: { chart_data: @commits_per_month.to_json.html_safe } }
.row .row
.col-md-6 .col-md-6
.col-md-6 .col-md-6
%p.slead %p.slead
= _("Commits per weekday") = _("Commits per weekday")
%div %div
%canvas#weekday-chart #js-weekday-chart{ data: { chart_data: @commits_per_week_days.to_json.html_safe } }
.row .row
.col-md-6 .col-md-6
.col-md-6 .col-md-6
%p.slead %p.slead
= _("Commits per day hour (UTC)") = _("Commits per day hour (UTC)")
%div %div
%canvas#hour-chart #js-hour-chart{ data: { chart_data: @commits_per_time.to_json.html_safe } }
-# haml-lint:disable InlineJavaScript
%script#projectChartData{ type: "application/json" }
- projectChartData = {};
- projectChartData['hour'] = @commits_per_time
- projectChartData['weekDays'] = @commits_per_week_days
- projectChartData['month'] = @commits_per_month
- projectChartData['languages'] = @languages
= projectChartData.to_json.html_safe
...@@ -5996,6 +5996,9 @@ msgstr "" ...@@ -5996,6 +5996,9 @@ msgstr ""
msgid "Date range cannot exceed %{maxDateRange} days." msgid "Date range cannot exceed %{maxDateRange} days."
msgstr "" msgstr ""
msgid "Day of month"
msgstr ""
msgid "DayTitle|F" msgid "DayTitle|F"
msgstr "" msgstr ""
...@@ -10004,6 +10007,9 @@ msgstr "" ...@@ -10004,6 +10007,9 @@ msgstr ""
msgid "Hook was successfully updated." msgid "Hook was successfully updated."
msgstr "" msgstr ""
msgid "Hour (UTC)"
msgstr ""
msgid "Housekeeping" msgid "Housekeeping"
msgstr "" msgstr ""
...@@ -12803,6 +12809,9 @@ msgstr "" ...@@ -12803,6 +12809,9 @@ msgstr ""
msgid "No, not interested right now" msgid "No, not interested right now"
msgstr "" msgstr ""
msgid "No. of commits"
msgstr ""
msgid "Nobody has starred this repository yet" msgid "Nobody has starred this repository yet"
msgstr "" msgstr ""
...@@ -13531,6 +13540,9 @@ msgstr "" ...@@ -13531,6 +13540,9 @@ msgstr ""
msgid "People without permission will never get a notification." msgid "People without permission will never get a notification."
msgstr "" msgstr ""
msgid "Percentage"
msgstr ""
msgid "Perform advanced options such as changing path, transferring, or removing the group." msgid "Perform advanced options such as changing path, transferring, or removing the group."
msgstr "" msgstr ""
...@@ -20797,6 +20809,9 @@ msgstr "" ...@@ -20797,6 +20809,9 @@ msgstr ""
msgid "Used by members to sign in to your group in GitLab" msgid "Used by members to sign in to your group in GitLab"
msgstr "" msgstr ""
msgid "Used programming language"
msgstr ""
msgid "Used to help configure your identity provider" msgid "Used to help configure your identity provider"
msgstr "" msgstr ""
...@@ -21486,6 +21501,9 @@ msgstr "" ...@@ -21486,6 +21501,9 @@ msgstr ""
msgid "Wednesday" msgid "Wednesday"
msgstr "" msgstr ""
msgid "Weekday"
msgstr ""
msgid "Weeks" msgid "Weeks"
msgstr "" msgstr ""
......
...@@ -22,20 +22,12 @@ describe 'Project Graph', :js do ...@@ -22,20 +22,12 @@ describe 'Project Graph', :js do
end end
end end
shared_examples 'page should have languages graphs' do
it 'renders languages' do
expect(page).to have_content(/Ruby 66.* %/)
expect(page).to have_content(/JavaScript 22.* %/)
end
end
context 'commits graph' do context 'commits graph' do
before do before do
visit commits_project_graph_path(project, 'master') visit commits_project_graph_path(project, 'master')
end end
it_behaves_like 'page should have commits graphs' it_behaves_like 'page should have commits graphs'
it_behaves_like 'page should have languages graphs'
end end
context 'languages graph' do context 'languages graph' do
...@@ -44,7 +36,6 @@ describe 'Project Graph', :js do ...@@ -44,7 +36,6 @@ describe 'Project Graph', :js do
end end
it_behaves_like 'page should have commits graphs' it_behaves_like 'page should have commits graphs'
it_behaves_like 'page should have languages graphs'
end end
context 'charts graph' do context 'charts graph' do
...@@ -53,7 +44,6 @@ describe 'Project Graph', :js do ...@@ -53,7 +44,6 @@ describe 'Project Graph', :js do
end end
it_behaves_like 'page should have commits graphs' it_behaves_like 'page should have commits graphs'
it_behaves_like 'page should have languages graphs'
end end
context 'chart graph with HTML escaped branch name' do context 'chart graph with HTML escaped branch name' do
......
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