Commit 18b361cf authored by Phil Hughes's avatar Phil Hughes

Group the contributing calendar by day

This aligns the boxes correctly with the day on the left side of the calendar
parent 36fdbc6e
......@@ -19,7 +19,6 @@
#= require jquery.scrollTo
#= require jquery.turbolinks
#= require d3
#= require cal-heatmap
#= require turbolinks
#= require autosave
#= require bootstrap/affix
......
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<br />#{gl.utils.formatDate parseInt(stamp.date) * 1000}"
.attr 'class', (stamp) ->
extraClass = ''
"#{stamp.count} contributions<br />#{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
......@@ -8,7 +8,6 @@
*= require select2
*= require_self
*= require dropzone/basic
*= require cal-heatmap
*= require cropper.css
*= require animate
*/
......
......@@ -26,75 +26,28 @@
}
}
/**
* This overwrites the default values of the cal-heatmap gem
*/
.calendar {
.qi {
fill: #fff;
}
.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;
}
.user-calendar {
text-align: center;
.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;
}
......@@ -66,12 +66,6 @@
}
}
.calendar-hint {
margin-top: -12px;
float: right;
font-size: 12px;
}
.profile-link-holder {
display: inline;
......
......@@ -74,8 +74,6 @@ def snippets
def calendar
calendar = contributions_calendar
@timestamps = calendar.timestamps
@starting_year = calendar.starting_year
@starting_month = calendar.starting_month
render 'calendar', layout: false
end
......
#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}'
);
......@@ -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} }
......
......@@ -19,7 +19,7 @@ def timestamps
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
......
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