diff options
-rw-r--r-- | app/assets/javascripts/calendar.js.coffee | 195 |
1 files changed, 105 insertions, 90 deletions
diff --git a/app/assets/javascripts/calendar.js.coffee b/app/assets/javascripts/calendar.js.coffee index 701117747d5..f9c7bffdadb 100644 --- a/app/assets/javascripts/calendar.js.coffee +++ b/app/assets/javascripts/calendar.js.coffee @@ -1,32 +1,34 @@ class @Calendar - constructor: (timestamps, calendar_activities_path) -> - currentSelectedDate = '' - daySpace = 1 - daySize = 15 - daySizeWithSpace = daySize + (daySpace * 2) + constructor: (timestamps, @calendar_activities_path) -> + @currentSelectedDate = '' + @daySpace = 1 + @daySize = 15 + @daySizeWithSpace = @daySize + (@daySpace * 2) + @monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + @months = [] + @highestValue = 0 # Get the highest value from the timestampes - highestValue = 0 - _.each timestamps, (count) -> - if count > highestValue - highestValue = count + _.each timestamps, (count) => + if count > @highestValue + @highestValue = count # 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 = [] + @timestampsTmp = [] i = 0 group = 0 - _.each timestamps, (count, date) -> + _.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 [] + @timestampsTmp.push [] group++ - innerArray = timestampsTmp[group-1] + innerArray = @timestampsTmp[group-1] # Push to the inner array the values that will be used to render map innerArray.push @@ -36,64 +38,61 @@ class @Calendar i++ - # Color function for chart - color = d3 - .scale - .linear() - .range(['#acd5f2', '#254e77']) - .domain([0, highestValue]) + # Init color functions + @color = @initColor() + @colorKey = @initColorKey() - # Color function for key - colorKey = d3 - .scale - .linear() - .range(['#acd5f2', '#254e77']) - .domain([0, 3]) - keyColors = ['#ededed', colorKey(0), colorKey(1), colorKey(2), colorKey(3)] + # Init the svg element + @renderSvg(group) + @renderDays() + @renderMonths() + @renderDayTitles() + @renderKey() + + @initTooltips() - monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] - months = [] - svg = d3.select '.js-contrib-calendar' + renderSvg: (group) -> + @svg = d3.select '.js-contrib-calendar' .append 'svg' - .attr 'width', 54 * daySizeWithSpace + .attr 'width', (group + 1) * @daySizeWithSpace .attr 'height', 167 .attr 'class', 'contrib-calendar' - # Setup each day box - svg.selectAll 'g' - .data timestampsTmp + renderDays: -> + @svg.selectAll 'g' + .data @timestampsTmp .enter() .append 'g' - .attr 'transform', (group, i) -> - _.each group, (stamp, a) -> + .attr 'transform', (group, i) => + _.each group, (stamp, a) => if a is 0 and stamp.day is 0 month = stamp.date.getMonth() - x = (daySizeWithSpace * i + 1) + daySizeWithSpace - lastMonth = _.last(months) + x = (@daySizeWithSpace * i + 1) + @daySizeWithSpace + lastMonth = _.last(@months) if lastMonth? lastMonthX = lastMonth.x if !lastMonth? - months.push + @months.push month: month x: x - else if month isnt lastMonth.month and x - daySizeWithSpace isnt lastMonthX - months.push + else if month isnt lastMonth.month and x - @daySizeWithSpace isnt lastMonthX + @months.push month: month x: x - "translate(#{(daySizeWithSpace * i + 1) + daySizeWithSpace}, 18)" + "translate(#{(@daySizeWithSpace * i + 1) + @daySizeWithSpace}, 18)" .selectAll 'rect' .data (stamp) -> stamp .enter() .append 'rect' .attr 'x', '0' - .attr 'y', (stamp, i) -> - (daySizeWithSpace * stamp.day) - .attr 'width', daySize - .attr 'height', daySize - .attr 'title', (stamp) -> + .attr 'y', (stamp, i) => + (@daySizeWithSpace * stamp.day) + .attr 'width', @daySize + .attr 'height', @daySize + .attr 'title', (stamp) => contribText = 'No contributions' if stamp.count > 0 @@ -103,55 +102,26 @@ class @Calendar "#{contribText}<br />#{date}" .attr 'class', 'user-contrib-cell js-tooltip' - .attr 'fill', (stamp) -> + .attr 'fill', (stamp) => if stamp.count isnt 0 - color(stamp.count) + @color(stamp.count) else '#ededed' .attr 'data-container', 'body' - .on 'click', (stamp) -> - if currentSelectedDate isnt stamp.date - currentSelectedDate = stamp.date - formatted_date = currentSelectedDate.getFullYear() + "-" + (currentSelectedDate.getMonth()+1) + "-" + currentSelectedDate.getDate() - - $.ajax - url: calendar_activities_path - data: - date: formatted_date - cache: false - dataType: 'html' - beforeSend: -> - $('.user-calendar-activities').html '<div class="text-center"><i class="fa fa-spinner fa-spin user-calendar-activities-loading"></i></div>' - success: (data) -> - $('.user-calendar-activities').html data - else - $('.user-calendar-activities').html '' - - # Month titles - svg.append 'g' - .selectAll 'text' - .data months - .enter() - .append 'text' - .attr 'x', (date) -> - date.x - .attr 'y', 10 - .attr 'class', 'user-contrib-text' - .text (date) -> - monthNames[date.month] + .on 'click', @clickDay - # Day titles + renderDayTitles: -> days = [{ text: 'M' - y: 29 + (daySizeWithSpace * 1) + y: 29 + (@daySizeWithSpace * 1) }, { text: 'W' - y: 29 + (daySizeWithSpace * 3) + y: 29 + (@daySizeWithSpace * 3) }, { text: 'F' - y: 29 + (daySizeWithSpace * 5) + y: 29 + (@daySizeWithSpace * 5) }] - svg.append 'g' + @svg.append 'g' .selectAll 'text' .data days .enter() @@ -164,20 +134,65 @@ class @Calendar day.text .attr 'class', 'user-contrib-text' - # Key with color boxes - svg.append 'g' - .attr 'transform', "translate(18, #{daySizeWithSpace * 8 + 16})" + renderMonths: -> + @svg.append 'g' + .selectAll 'text' + .data @months + .enter() + .append 'text' + .attr 'x', (date) -> + date.x + .attr 'y', 10 + .attr 'class', 'user-contrib-text' + .text (date) => + @monthNames[date.month] + + renderKey: -> + keyColors = ['#ededed', @colorKey(0), @colorKey(1), @colorKey(2), @colorKey(3)] + @svg.append 'g' + .attr 'transform', "translate(18, #{@daySizeWithSpace * 8 + 16})" .selectAll 'rect' .data keyColors .enter() .append 'rect' - .attr 'width', daySize - .attr 'height', daySize - .attr 'x', (color, i) -> - daySizeWithSpace * i + .attr 'width', @daySize + .attr 'height', @daySize + .attr 'x', (color, i) => + @daySizeWithSpace * i .attr 'y', 0 .attr 'fill', (color) -> color + initColor: -> + d3.scale + .linear() + .range(['#acd5f2', '#254e77']) + .domain([0, @highestValue]) + + initColorKey: -> + d3.scale + .linear() + .range(['#acd5f2', '#254e77']) + .domain([0, 3]) + + clickDay: (stamp) -> + if @currentSelectedDate isnt stamp.date + @currentSelectedDate = stamp.date + formatted_date = @currentSelectedDate.getFullYear() + "-" + (@currentSelectedDate.getMonth()+1) + "-" + @currentSelectedDate.getDate() + + $.ajax + url: @calendar_activities_path + data: + date: formatted_date + cache: false + dataType: 'html' + beforeSend: -> + $('.user-calendar-activities').html '<div class="text-center"><i class="fa fa-spinner fa-spin user-calendar-activities-loading"></i></div>' + success: (data) -> + $('.user-calendar-activities').html data + else + $('.user-calendar-activities').html '' + + initTooltips: -> $('.js-contrib-calendar .js-tooltip').tooltip html: true |