deal with off days

This commit is contained in:
Radek Stepan 2013-08-19 18:16:51 +01:00
parent b09e68dac9
commit 6d21281b22
2 changed files with 49 additions and 11 deletions

View File

@ -5,24 +5,51 @@ d3 = require 'd3'
reg = require './regex' reg = require './regex'
module.exports = module.exports =
# Map closed issues ready to be visualized by Rickshaw. # Map closed issues.
# Assumes collection has been `filter`ed and is ordered.
'actual': (collection, created_at, total, cb) -> 'actual': (collection, created_at, total, cb) ->
head = [ { date: new Date(created_at), points: total } ] head = [ { date: new Date(created_at), points: total } ]
rest = _.map collection, ({ closed_at, size }) -> rest = _.map collection, ({ closed_at, size }) ->
{ date: new Date(closed_at), points: total -= size } { date: new Date(closed_at), points: total -= size }
cb null, head.concat rest cb null, head.concat rest
# Map ideal velocity for each day ready to be visualized by Rickshaw. # Map ideal velocity for each day.
'ideal': (a, b, total, cb) -> 'ideal': (a, b, off_days, total, cb) ->
# Swap? # Swap?
[ b, a ] = [ a, b ] if b < a [ b, a ] = [ a, b ] if b < a
cb null, [ # We start here adding days to `d`.
{ date: new Date(a), points: total } [ y, m, d ] = _.map a.match(reg.datetime)[1].split('-'), (v) -> parseInt v
{ date: new Date(b), points: 0 } # We want to end here.
] cutoff = new Date(b)
# Go through the beginning to the end skipping off days.
days = [] ; length = 0
do once = (inc = 0) ->
# A new day.
day = new Date y, m - 1, d + inc
# Does this day count?
day_of = 7 if !day_of = day.getDay()
if day_of in off_days
days.push { date: day, off_day: yes }
else
length += 1
days.push { date: day }
# Go again?
once(inc + 1) unless day > cutoff
# Map points on the array of days now.
velocity = total / (length - 1)
days = _.map days, (day, i) ->
day.points = total
total -= velocity if days[i] and not days[i].off_day
day
cb null, days
# Render the D3 chart.
'render': ([ actual, ideal ], cb) -> 'render': ([ actual, ideal ], cb) ->
# Get available space. # Get available space.
{ height, width } = document.querySelector('#graph').getBoundingClientRect() { height, width } = document.querySelector('#graph').getBoundingClientRect()
@ -52,7 +79,7 @@ module.exports =
# Line generator. # Line generator.
line = d3.svg.line() line = d3.svg.line()
.interpolate("basis") .interpolate("precise")
.x( (d) -> x(d.date) ) .x( (d) -> x(d.date) )
.y( (d) -> y(d.points) ) .y( (d) -> y(d.points) )

View File

@ -52,8 +52,19 @@ class exports.Repo
(total = self.issues.open.points + self.issues.closed.points) (total = self.issues.open.points + self.issues.closed.points)
async.parallel [ async.parallel [
_.partial(graph.actual, self.issues.closed.data, self.milestone.created_at, total) _.partial(
_.partial(graph.ideal, self.milestone.created_at, self.milestone.due_on, total) graph.actual,
self.issues.closed.data,
self.milestone.created_at,
total
)
_.partial(
graph.ideal,
self.milestone.created_at,
self.milestone.due_on,
self.off_days or [],
total
)
], (err, values) -> ], (err, values) ->
# Render the body. # Render the body.
render 'body', 'graph' render 'body', 'graph'