Skip to content

Commit

Permalink
Separating out the Redmine Burndown plugin from our Redmine install.
Browse files Browse the repository at this point in the history
  • Loading branch information
danhodos committed Jan 25, 2009
0 parents commit 10a89f4
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 0 deletions.
24 changes: 24 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Redmine Burndowns

## Introduction

This plugin adds a 'Burndown' tab to your Project Menu for any Project with the 'Burndowns' module enabled (Settings>Modules).

This tab will show the Burndown chart for the current Sprint (cough Version cough), and also give a sidebar listing of all previous Sprints to see their Burndown chart as well. The Burndown Chart shows the current work remaining in red and an ideal trend line in grey.

## Installation
The Redmine Burndowns plugin depends on the excellent googlecharts gems by Matt Aimonetti. This can be installed with:

sudo gem install mattetti-googlecharts --source=http://gems.github.com

If you'd like, you may also unpack the gem into your Redmine deploy by adding the following to your environment.rb file:

config.gem 'mattetti-googlecharts', :lib => 'gchart', :version => ">=1.3.6"

and then running:

rake gems:unpack

Copyright (c) 2009 [Scrum Alliance](www.scrumalliance.org), released under the MIT license.

Authored by [Dan Hodos](mailto:danhodos[at]gmail[dot]com)
17 changes: 17 additions & 0 deletions app/controllers/burndowns_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class BurndownsController < ApplicationController
unloadable
menu_item :burndown

before_filter :find_version_and_project, :authorize, :only => [:show]

def show
@chart = BurndownChart.new(@version)
end

private
def find_version_and_project
@project = Project.find(params[:project_id])
@version = params[:id] ? @project.versions.find(params[:id]) : @project.current_version
render_error("There is no current Sprint for this Project") and return unless @version
end
end
58 changes: 58 additions & 0 deletions app/models/burndown_chart.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
class BurndownChart
attr_accessor :dates, :version, :start_date

delegate :to_s, :to => :chart

def initialize(version)
self.version = version

self.start_date = version.created_on.to_date
end_date = version.effective_date.to_date
self.dates = (start_date..end_date).inject([]) { |accum, date| accum << date }
end

def chart
Gchart.line(
:size => '750x400',
:data => data,
:axis_with_labels => 'x,y',
:axis_labels => [dates.map {|d| d.strftime("%m-%d") }],
:custom => "chxr=1,0,#{sprint_data.max}",
:line_colors => "DDDDDD,FF0000"
)
end

def data
[ideal_data, sprint_data]
end

def sprint_data
@sprint_data ||= dates.map do |date|
issues = all_issues.select {|issue| issue.created_on.to_date <= date }
issues.inject(0) do |total_hours_left, issue|
done_ratio_details = issue.journals.map(&:details).flatten.select {|detail| 'done_ratio' == detail.prop_key }
details_today_or_earlier = done_ratio_details.select {|a| a.journal.created_on.to_date <= date }

last_done_ratio_change = details_today_or_earlier.sort_by {|a| a.journal.created_on }.last

ratio = if last_done_ratio_change
last_done_ratio_change.value
elsif done_ratio_details.size > 0
0
else
issue.done_ratio.to_i
end

total_hours_left += (issue.estimated_hours.to_i * (100-ratio.to_i)/100)
end
end
end

def ideal_data
[sprint_data.first, 0]
end

def all_issues
version.fixed_issues.find(:all, :include => [{:journals => :details}, :relations_from, :relations_to])
end
end
12 changes: 12 additions & 0 deletions app/views/burndowns/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<h2><%= @version.name %> <%= l(:burndown) %></h2>

<p><%= image_tag(@chart.to_s) %></p>

<% content_for :sidebar do -%>
<h3><%= l(:label_version_plural) %></h3>
<ul id="sprint_burndown_list">
<% @project.versions.each do |version| -%>
<li<%= %Q[ class="selected"] if @version == version %>><%= link_to(version.name, show_burndown_path(:project_id => @project, :id => version)) %></li>
<% end -%>
</ul>
<% end -%>
2 changes: 2 additions & 0 deletions assets/stylesheets/burndowns.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#sprint_burndown_list { padding: 0; list-style-type: none; }
#sprint_burndown_list li.selected { font-weight: bold; }
23 changes: 23 additions & 0 deletions init.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'redmine'
require 'gchart'

require_dependency 'burndown_listener'
require_dependency 'scrum_alliance/redmine/current_version_extension'

require 'dispatcher'
Dispatcher.to_prepare do
Project.class_eval { include ScrumAlliance::Redmine::CurrentVersionExtension }
end

Redmine::Plugin.register :burndown do
name 'Redmine Burndown plugin'
author 'Dan Hodos'
description 'Generates a simple Burndown chart for using Redmine in Scrum environments'
version '1.1.3'

project_module :burndowns do
permission :show_burndown, :burndowns => :show, :public => true
end

menu :project_menu, :burndown, { :controller => 'burndowns', :action => 'show' }, :param => :project_id, :before => :activity
end
1 change: 1 addition & 0 deletions lang/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
burndown: Burndown
5 changes: 5 additions & 0 deletions lib/burndown_listener.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class BurndownListener < Redmine::Hook::ViewListener
def view_layouts_base_html_head(context={})
stylesheet_link_tag('burndowns', :plugin => 'redmine_burndown')
end
end
9 changes: 9 additions & 0 deletions lib/scrum_alliance/redmine/current_version_extension.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module ScrumAlliance
module Redmine
module CurrentVersionExtension
def current_version
versions.detect {|version| version.created_on.to_date <= Date.current && version.effective_date >= Date.current }
end
end # CurrentVersionExtension
end # Redmine
end # ScrumAlliance
2 changes: 2 additions & 0 deletions routes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
map.latest_burndown 'projects/:project_id/burndown', :controller => 'burndowns', :action => 'show'
map.show_burndown 'projects/:project_id/burndowns/:id', :controller => 'burndowns', :action => 'show'
5 changes: 5 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Load the normal Rails helper
require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')

# Ensure that we are using the temporary fixture path
Engines::Testing.set_fixture_path

0 comments on commit 10a89f4

Please sign in to comment.