diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee
index bffce5a0c0f..ff69e27bbcf 100644
--- a/app/assets/javascripts/application.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -19,7 +19,6 @@
#= require jquery.scrollTo
#= require jquery.turbolinks
#= require d3
-#= require cal-heatmap
#= require turbolinks
#= require autosave
#= require bootstrap/affix
diff --git a/app/assets/javascripts/calendar.js.coffee b/app/assets/javascripts/calendar.js.coffee
index ec153f61c2a..9c4d529f7e9 100644
--- a/app/assets/javascripts/calendar.js.coffee
+++ b/app/assets/javascripts/calendar.js.coffee
@@ -1,52 +1,83 @@
class @Calendar
- constructor: (timestamps, starting_year, starting_month, calendar_activities_path) ->
+ constructor: (timestamps, calendar_activities_path) ->
# Get the highest value from the timestampes
highestValue = 0
_.each timestamps, (count) ->
if count > highestValue
highestValue = count
- timestamps = _.chain(timestamps)
- .map (stamp, key) ->
- {
- count: stamp
- date: key
- }
- .groupBy (stamp, i) ->
- Math.floor i / 7
- .toArray()
- .value()
+ # 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
+ timestampsTmp = []
+ i = 0
+ group = 0
+ _.each timestamps, (count, date) ->
+ newDate = new Date parseInt(date) * 1000
+ day = newDate.getDay()
+
+ # Create a new group array if this is the first day of the week
+ # or if is first object
+ if (day is 0 and i isnt 0) or i is 0
+ timestampsTmp.push []
+ group++
+
+ innerArray = timestampsTmp[group-1]
+
+ # Push to the inner array the values that will be used to render map
+ innerArray.push
+ count: count
+ date: newDate
+ day: day
+
+ i++
+
+ # Color function for chart
+ color = d3
+ .scale
+ .linear()
+ .range(['#acd5f2', '#254e77'])
+ .domain([0, highestValue])
+
+ # Color function for key
+ colorKey = d3
+ .scale
+ .linear()
+ .range(['#acd5f2', '#254e77'])
+ .domain([0, 3])
+ keyColors = ['#ededed', colorKey(0), colorKey(1), colorKey(2), colorKey(3)]
monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
months = []
- svg = d3.select '#cal-heatmap'
+ svg = d3.select '.js-contrib-calendar'
.append 'svg'
- .attr 'width', 53 * 17
- .attr 'height', 140
+ .attr 'width', 54 * 17
+ .attr 'height', 167
+ .attr 'class', 'contrib-calendar'
# Setup each day box
svg.selectAll 'g'
- .data timestamps
+ .data timestampsTmp
.enter()
.append 'g'
.attr 'transform', (group, i) ->
- _.each group, (stamp) ->
- month = new Date(parseInt(stamp.date) * 1000).getMonth()
- x = 17 * i + 1
- lastMonth = _.last(months)
+ _.each group, (stamp, a) ->
+ if a is 0 and stamp.day is 0
+ month = stamp.date.getMonth()
+ x = (17 * i + 1) + 17
+ lastMonth = _.last(months)
+ if lastMonth?
+ lastMonthX = lastMonth.x
- # If undefined, push
- if !lastMonth?
- months.push
- month: month
- x: x
- else if lastMonth.x is x
- lastMonth.month = month
- else if lastMonth.month isnt month
+ if !lastMonth?
months.push
month: month
x: x
- "translate(#{17 * i + 1}, 18)"
+ else if month isnt lastMonth.month and x - 17 isnt lastMonthX
+ months.push
+ month: month
+ x: x
+
+ "translate(#{(17 * i + 1) + 17}, 18)"
.selectAll 'rect'
.data (stamp) ->
stamp
@@ -54,22 +85,20 @@ class @Calendar
.append 'rect'
.attr 'x', '0'
.attr 'y', (stamp, i) ->
- 17 * i
+ (17 * stamp.day)
.attr 'width', 15
.attr 'height', 15
.attr 'title', (stamp) ->
- "#{stamp.count} contributions
#{gl.utils.formatDate parseInt(stamp.date) * 1000}"
- .attr 'class', (stamp) ->
- extraClass = ''
+ "#{stamp.count} contributions
#{gl.utils.formatDate stamp.date}"
+ .attr 'class', 'user-contrib-cell js-tooltip'
+ .attr 'fill', (stamp) ->
if stamp.count isnt 0
- diff = stamp.count / highestValue
- classNumber = Math.floor (diff / 0.25) + 1
- extraClass += "user-contrib-cell-#{classNumber}"
-
- "user-contrib-cell #{extraClass} js-tooltip"
+ color(stamp.count)
+ else
+ '#ededed'
.attr 'data-container', 'body'
.on 'click', (stamp) ->
- date = new Date(parseInt(stamp.date) * 1000)
+ date = stamp.date
formated_date = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate()
$.ajax
url: calendar_activities_path
@@ -80,6 +109,7 @@ class @Calendar
success: (data) ->
$(".user-calendar-activities").html data
+ # Month titles
svg.append 'g'
.selectAll 'text'
.data months
@@ -92,5 +122,44 @@ class @Calendar
.text (date) ->
monthNames[date.month]
- $('#cal-heatmap .js-tooltip').tooltip
+ # Day titles
+ days = [{
+ text: 'M'
+ y: 29 + (17 * 1)
+ }, {
+ text: 'W'
+ y: 29 + (17 * 3)
+ }, {
+ text: 'F'
+ y: 29 + (17 * 5)
+ }]
+ svg.append 'g'
+ .selectAll 'text'
+ .data days
+ .enter()
+ .append 'text'
+ .attr 'text-anchor', 'middle'
+ .attr 'x', 8
+ .attr 'y', (day) ->
+ day.y
+ .text (day) ->
+ day.text
+ .attr 'class', 'user-contrib-text'
+
+ # Key with color boxes
+ svg.append 'g'
+ .attr 'transform', "translate(18, #{17 * 8 + 16})"
+ .selectAll 'rect'
+ .data keyColors
+ .enter()
+ .append 'rect'
+ .attr 'width', 15
+ .attr 'height', 15
+ .attr 'x', (color, i) ->
+ 17 * i
+ .attr 'y', 0
+ .attr 'fill', (color) ->
+ color
+
+ $('.js-contrib-calendar .js-tooltip').tooltip
html: true
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index 69b3b6586de..efdb2b06a8c 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -8,7 +8,6 @@
*= require select2
*= require_self
*= require dropzone/basic
- *= require cal-heatmap
*= require cropper.css
*= require animate
*/
diff --git a/app/assets/stylesheets/framework/calendar.scss b/app/assets/stylesheets/framework/calendar.scss
index da03454d807..5b48801485b 100644
--- a/app/assets/stylesheets/framework/calendar.scss
+++ b/app/assets/stylesheets/framework/calendar.scss
@@ -26,75 +26,28 @@
}
}
-/**
-* This overwrites the default values of the cal-heatmap gem
-*/
-.calendar {
- .qi {
- fill: #fff;
- }
+.user-calendar {
+ text-align: center;
- .q1 {
- fill: #ededed !important;
- }
-
- .q2 {
- fill: #acd5f2 !important;
- }
-
- .q3 {
- fill: #7fa8d1 !important;
- }
-
- .q4 {
- fill: #49729b !important;
- }
-
- .q5 {
- fill: #254e77 !important;
- }
-
- .future {
- visibility: hidden;
- }
-
- .domain-background {
- fill: none;
- shape-rendering: crispedges;
- }
-
- .ch-tooltip {
- padding: 3px;
- font-weight: 550;
+ .calendar {
+ display: inline-block;
}
}
.user-contrib-cell {
- fill: #ededed;
- cursor: pointer;
-
&:hover {
+ cursor: pointer;
stroke: #000;
}
}
-.user-contrib-cell-1 {
- fill: #acd5f2;
-}
-
-.user-contrib-cell-3 {
- fill: #7fa8d1;
-}
-
-.user-contrib-cell-4 {
- fill: #49729b;
-}
-
-.user-contrib-cell-5 {
- fill: #254e77;
-}
-
.user-contrib-text {
font-size: 12px;
fill: #959494;
}
+
+.calendar-hint {
+ margin-top: -23px;
+ float: right;
+ font-size: 12px;
+}
diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss
index 843379a3f54..ef375e1386c 100644
--- a/app/assets/stylesheets/pages/profile.scss
+++ b/app/assets/stylesheets/pages/profile.scss
@@ -66,12 +66,6 @@
}
}
-.calendar-hint {
- margin-top: -12px;
- float: right;
- font-size: 12px;
-}
-
.profile-link-holder {
display: inline;
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 799421c185b..a99632454d9 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -74,8 +74,6 @@ class UsersController < ApplicationController
def calendar
calendar = contributions_calendar
@timestamps = calendar.timestamps
- @starting_year = calendar.starting_year
- @starting_month = calendar.starting_month
render 'calendar', layout: false
end
diff --git a/app/views/users/calendar.html.haml b/app/views/users/calendar.html.haml
index 2abee8be2a6..77f2ddefb1e 100644
--- a/app/views/users/calendar.html.haml
+++ b/app/views/users/calendar.html.haml
@@ -1,8 +1,9 @@
-#cal-heatmap.calendar
- :javascript
- new Calendar(
- #{@timestamps.to_json},
- #{@starting_year},
- #{@starting_month},
- '#{user_calendar_activities_path}'
- );
+.clearfix.calendar
+ .js-contrib-calendar
+ .calendar-hint
+ Summary of issues, merge requests, and push events
+:javascript
+ new Calendar(
+ #{@timestamps.to_json},
+ '#{user_calendar_activities_path}'
+ );
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 9017fd54fcc..0c513308308 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -89,10 +89,9 @@
.tab-content
#activity.tab-pane
.row-content-block.calender-block.white.second-block.hidden-xs
- %div{ class: container_class }
- .user-calendar{data: {href: user_calendar_path}}
- %h4.center.light
- %i.fa.fa-spinner.fa-spin
+ .user-calendar{data: {href: user_calendar_path}}
+ %h4.center.light
+ %i.fa.fa-spinner.fa-spin
.user-calendar-activities
.content_list{ data: {href: user_path} }
diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb
index 85583dce9ee..9dc2602867e 100644
--- a/lib/gitlab/contributions_calendar.rb
+++ b/lib/gitlab/contributions_calendar.rb
@@ -19,7 +19,7 @@ module Gitlab
select('date(created_at) as date, count(id) as total_amount').
map(&:attributes)
- dates = (1.year.ago.to_date..(Date.today + 1.day)).to_a
+ dates = (1.year.ago.to_date..Date.today).to_a
dates.each do |date|
date_id = date.to_time.to_i.to_s