diff --git a/app/assets/javascripts/users/activity_calendar.js b/app/assets/javascripts/users/activity_calendar.js
index b109eb2b223..f091e319f44 100644
--- a/app/assets/javascripts/users/activity_calendar.js
+++ b/app/assets/javascripts/users/activity_calendar.js
@@ -1,5 +1,3 @@
-/* eslint-disable no-var, vars-on-top, one-var, one-var-declaration-per-line, max-len, class-methods-use-this */
-
import d3 from 'd3';
const LOADING_HTML = `
@@ -8,8 +6,22 @@ const LOADING_HTML = `
`;
+function formatTooltipText({ date, count }) {
+ const dateObject = new Date(date);
+ const dateDayName = gl.utils.getDayName(dateObject);
+ const dateText = dateObject.format('mmm d, yyyy');
+
+ let contribText = 'No contributions';
+ if (count > 0) {
+ contribText = `${count} contribution${count > 1 ? 's' : ''}`;
+ }
+ return `${contribText}
${dateDayName} ${dateText}`;
+}
+
+const initColorKey = () => d3.scale.linear().range(['#acd5f2', '#254e77']).domain([0, 3]);
+
export default class ActivityCalendar {
- constructor(timestamps, calendarActivitiesPath) {
+ constructor(container, timestamps, calendarActivitiesPath) {
this.calendarActivitiesPath = calendarActivitiesPath;
this.clickDay = this.clickDay.bind(this);
this.currentSelectedDate = '';
@@ -22,22 +34,22 @@ export default class ActivityCalendar {
// Loop through the timestamps to create a group of objects
// The group of objects will be grouped based on the day of the week they are
this.timestampsTmp = [];
- var group = 0;
+ let group = 0;
- var today = new Date();
+ const today = new Date();
today.setHours(0, 0, 0, 0, 0);
- var oneYearAgo = new Date(today);
+ const oneYearAgo = new Date(today);
oneYearAgo.setFullYear(today.getFullYear() - 1);
- var days = gl.utils.getDayDifference(oneYearAgo, today);
+ const days = gl.utils.getDayDifference(oneYearAgo, today);
- for (var i = 0; i <= days; i += 1) {
- var date = new Date(oneYearAgo);
+ for (let i = 0; i <= days; i += 1) {
+ const date = new Date(oneYearAgo);
date.setDate(date.getDate() + i);
- var day = date.getDay();
- var count = timestamps[date.format('yyyy-mm-dd')] || 0;
+ const day = date.getDay();
+ const count = timestamps[date.format('yyyy-mm-dd')] || 0;
// Create a new group array if this is the first day of the week
// or if is first object
@@ -47,28 +59,30 @@ export default class ActivityCalendar {
}
// Push to the inner array the values that will be used to render map
- var innerArray = this.timestampsTmp[group - 1];
+ const innerArray = this.timestampsTmp[group - 1];
innerArray.push({ count, date, day });
}
// Init color functions
- this.colorKey = this.initColorKey();
+ this.colorKey = initColorKey();
this.color = this.initColor();
// Init the svg element
- this.renderSvg(group);
+ this.svg = this.renderSvg(container, group);
this.renderDays();
this.renderMonths();
this.renderDayTitles();
this.renderKey();
- this.initTooltips();
+
+ // Init tooltips
+ $(`${container} .js-tooltip`).tooltip({ html: true });
}
// Add extra padding for the last month label if it is also the last column
getExtraWidthPadding(group) {
- var extraWidthPadding = 0;
- var lastColMonth = this.timestampsTmp[group - 1][0].date.getMonth();
- var secondLastColMonth = this.timestampsTmp[group - 2][0].date.getMonth();
+ let extraWidthPadding = 0;
+ const lastColMonth = this.timestampsTmp[group - 1][0].date.getMonth();
+ const secondLastColMonth = this.timestampsTmp[group - 2][0].date.getMonth();
if (lastColMonth !== secondLastColMonth) {
extraWidthPadding = 3;
@@ -77,9 +91,9 @@ export default class ActivityCalendar {
return extraWidthPadding;
}
- renderSvg(group) {
- var width = ((group + 1) * this.daySizeWithSpace) + this.getExtraWidthPadding(group);
- this.svg = d3.select('.js-contrib-calendar')
+ renderSvg(container, group) {
+ const width = ((group + 1) * this.daySizeWithSpace) + this.getExtraWidthPadding(group);
+ return d3.select(container)
.append('svg')
.attr('width', width)
.attr('height', 167)
@@ -90,15 +104,14 @@ export default class ActivityCalendar {
this.svg.selectAll('g').data(this.timestampsTmp).enter().append('g')
.attr('transform', (group, i) => {
_.each(group, (stamp, a) => {
- var lastMonth, lastMonthX, month, x;
if (a === 0 && stamp.day === 0) {
- month = stamp.date.getMonth();
- x = (this.daySizeWithSpace * i) + 1 + this.daySizeWithSpace;
- lastMonth = _.last(this.months);
- if (lastMonth != null) {
- lastMonthX = lastMonth.x;
- }
- if (lastMonth == null || (month !== lastMonth.month && x - this.daySizeWithSpace !== lastMonthX)) {
+ const month = stamp.date.getMonth();
+ const x = (this.daySizeWithSpace * i) + 1 + this.daySizeWithSpace;
+ const lastMonth = _.last(this.months);
+ if (
+ lastMonth == null ||
+ (month !== lastMonth.month && x - this.daySizeWithSpace !== lastMonth.x)
+ ) {
this.months.push({ month, x });
}
}
@@ -106,29 +119,20 @@ export default class ActivityCalendar {
return `translate(${(this.daySizeWithSpace * i) + 1 + this.daySizeWithSpace}, 18)`;
})
.selectAll('rect')
- .data(stamp => stamp)
- .enter()
- .append('rect')
- .attr('x', '0')
- .attr('y', stamp => this.daySizeWithSpace * stamp.day)
- .attr('width', this.daySize)
- .attr('height', this.daySize)
- .attr('title', (stamp) => {
- var contribText, date, dateText;
- date = new Date(stamp.date);
- contribText = 'No contributions';
- if (stamp.count > 0) {
- contribText = `${stamp.count} contribution${stamp.count > 1 ? 's' : ''}`;
- }
- dateText = date.format('mmm d, yyyy');
- return `${contribText}
${gl.utils.getDayName(date)} ${dateText}`;
- })
- .attr('class', 'user-contrib-cell js-tooltip')
- .attr('fill', stamp => (
- stamp.count !== 0 ? this.color(Math.min(stamp.count, 40)) : '#ededed'
- ))
- .attr('data-container', 'body')
- .on('click', this.clickDay);
+ .data(stamp => stamp)
+ .enter()
+ .append('rect')
+ .attr('x', '0')
+ .attr('y', stamp => this.daySizeWithSpace * stamp.day)
+ .attr('width', this.daySize)
+ .attr('height', this.daySize)
+ .attr('fill', stamp => (
+ stamp.count !== 0 ? this.color(Math.min(stamp.count, 40)) : '#ededed'
+ ))
+ .attr('title', stamp => formatTooltipText(stamp))
+ .attr('class', 'user-contrib-cell js-tooltip')
+ .attr('data-container', 'body')
+ .on('click', this.clickDay);
}
renderDayTitles() {
@@ -190,15 +194,10 @@ export default class ActivityCalendar {
}
initColor() {
- var colorRange;
- colorRange = ['#ededed', this.colorKey(0), this.colorKey(1), this.colorKey(2), this.colorKey(3)];
+ const colorRange = ['#ededed', this.colorKey(0), this.colorKey(1), this.colorKey(2), this.colorKey(3)];
return d3.scale.threshold().domain([0, 10, 20, 30]).range(colorRange);
}
- initColorKey() {
- return d3.scale.linear().range(['#acd5f2', '#254e77']).domain([0, 3]);
- }
-
clickDay(stamp) {
if (this.currentSelectedDate !== stamp.date) {
this.currentSelectedDate = stamp.date;
@@ -222,8 +221,4 @@ export default class ActivityCalendar {
$('.user-calendar-activities').html('');
}
}
-
- initTooltips() {
- $('.js-contrib-calendar .js-tooltip').tooltip({ html: true });
- }
}
diff --git a/app/assets/javascripts/users/user_tabs.js b/app/assets/javascripts/users/user_tabs.js
index fd9fe597303..5fe6603ce7b 100644
--- a/app/assets/javascripts/users/user_tabs.js
+++ b/app/assets/javascripts/users/user_tabs.js
@@ -158,7 +158,7 @@ export default class UserTabs {
$calendarWrap.html(CALENDAR_TEMPLATE);
// eslint-disable-next-line no-new
- new ActivityCalendar(activityData, calendarActivitiesPath);
+ new ActivityCalendar('.js-contrib-calendar', activityData, calendarActivitiesPath);
},
});