ardekantur-gantty 0.1.2 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +10 -0
- data/lib/gantty.rb +247 -13
- data/spec/gantty_spec.rb +1 -1
- data/spec/task_spec.rb +20 -5
- data/spec/test_gantt_project.gan +84 -84
- metadata +5 -5
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
2
3
|
require 'rake/gempackagetask'
|
3
4
|
require 'rubygems/specification'
|
4
5
|
require 'spec/rake/spectask'
|
@@ -29,3 +30,12 @@ desc "install the gem locally"
|
|
29
30
|
task :install => [:package] do
|
30
31
|
sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
|
31
32
|
end
|
33
|
+
|
34
|
+
desc "generate rdoc documentation"
|
35
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
36
|
+
rdoc.rdoc_files.include('readme.md', 'LICENSE' ).
|
37
|
+
include('lib/**/*.rb')
|
38
|
+
|
39
|
+
rdoc.main = "readme.md"
|
40
|
+
rdoc.rdoc_dir = 'doc' # rdoc output folder
|
41
|
+
end
|
data/lib/gantty.rb
CHANGED
@@ -3,25 +3,56 @@ $:.unshift File.expand_path(File.dirname(__FILE__))
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'date'
|
5
5
|
require 'nokogiri'
|
6
|
+
require 'builder'
|
6
7
|
|
7
8
|
module Gantty
|
8
9
|
|
10
|
+
# A dual-lookup hash for priority conversions between GanttProject files and Gantty tasks.
|
9
11
|
PRIORITY = { :low => 0, :normal => 1, :medium => 1, :high => 2, 0 => :low, 1 => :normal, 2 => :high }
|
12
|
+
|
13
|
+
# Hardness links of related tasks.
|
10
14
|
HARDNESS = { :rubber => "Rubber", :strong => "Strong" }
|
15
|
+
|
16
|
+
# A lookup hash for converstions between GanttProject file priorities and the functions that dependencies of that value will call.
|
11
17
|
DEPENDS = { 1 => :add_starts_with, 2 => :add_starts_after, 3 => :add_finishes_with, 4 => :add_finishes_before }
|
18
|
+
|
19
|
+
# A reverse-lookup hash for dependency types between Gantty and GanttProject.
|
20
|
+
REVERSE_DEPENDS = { :starts_with => 1, :starts_after => 2, :finishes_with => 3, :finishes_before => 4 }
|
12
21
|
|
22
|
+
# Create a new task.
|
23
|
+
#
|
24
|
+
# task = Gantty::Task "New Task Name"
|
25
|
+
# task = Gantty::Task :name => "New Task Name"
|
26
|
+
#
|
27
|
+
# Only setting <tt>:name</tt> is supported in the hash instantiation right now.
|
13
28
|
def self.Task args
|
14
29
|
return Task.new(args)
|
15
30
|
end
|
16
31
|
|
32
|
+
# Create a new Gantt chart from a GanttProject <tt>.gan</tt> file.
|
33
|
+
#
|
34
|
+
# gantt = Gantty::Open('~/charts/example.gan')
|
17
35
|
def self.Open file
|
18
36
|
return GanttChart.new(file)
|
19
37
|
end
|
20
38
|
|
39
|
+
# Create a new Gantt chart from scratch.
|
40
|
+
#
|
41
|
+
# gantt = Gantty::New()
|
21
42
|
def self.New
|
22
43
|
return GanttChart.new
|
23
44
|
end
|
24
45
|
|
46
|
+
# Create a new Gantt Resource.
|
47
|
+
#
|
48
|
+
# bob = Gantty::Resource "Bob Beta"
|
49
|
+
# bob = Gantty::Resource :name => "Bob Beta"
|
50
|
+
#
|
51
|
+
# Only setting <tt>:name</tt> is supported in the hash instantiation right now.
|
52
|
+
def self.Resource args
|
53
|
+
return Resource.new(args)
|
54
|
+
end
|
55
|
+
|
25
56
|
class GanttChart
|
26
57
|
|
27
58
|
attr_accessor :resources, :tasks
|
@@ -38,13 +69,19 @@ module Gantty
|
|
38
69
|
def parse_gantt
|
39
70
|
depends = { 1 => [], 2 => [], 3 => [], 4 => [] }
|
40
71
|
@gantt.xpath('//resource').each { |r| @resources << Resource.new(r) }
|
41
|
-
@gantt.xpath('
|
42
|
-
|
72
|
+
@gantt.xpath('/project/tasks/task').each do |t|
|
73
|
+
created_task = Task.new(t)
|
74
|
+
add_subtasks_to_task t, created_task
|
75
|
+
@tasks << created_task
|
76
|
+
end
|
77
|
+
|
78
|
+
@gantt.xpath('//task').each do |t|
|
43
79
|
t.children.select { |c| c.name == "depend" }.each do |dependency|
|
44
80
|
depends[dependency.attributes["type"].to_i] << [t.attributes["id"].to_i, dependency.attributes["id"].to_i]
|
45
81
|
end
|
46
82
|
end
|
47
|
-
|
83
|
+
|
84
|
+
all_tasks.each do |task|
|
48
85
|
@gantt.xpath("//allocation[@task-id=#{task.id}]").each do |alloc|
|
49
86
|
task.coordinators += @resources.select { |r| r.id == alloc.attributes["resource-id"].to_i }
|
50
87
|
end
|
@@ -55,26 +92,181 @@ module Gantty
|
|
55
92
|
end
|
56
93
|
end
|
57
94
|
|
95
|
+
# Display all current tasks. A *current* *task* is defined as a task that has either started today, ended today,
|
96
|
+
# or begins before today and ends after today.
|
97
|
+
#
|
98
|
+
# tasks = @gantt.current_tasks
|
99
|
+
#
|
100
|
+
# Specify the parameter +date+ to see current tasks for that date, instead of today.
|
101
|
+
#
|
102
|
+
# tasks = @gantt.current_tasks Date.new(2008,1,6)
|
58
103
|
def current_tasks date = Date.today
|
59
|
-
|
104
|
+
all_tasks.select { |t| t.start <= date and t.end >= date }
|
105
|
+
end
|
106
|
+
|
107
|
+
def task_where cond, task_array = @tasks
|
108
|
+
task_array.each do |task|
|
109
|
+
found_task = true
|
110
|
+
cond.each { |property,value| found_task = false unless task.instance_variable_get("@#{property.to_s}") == value }
|
111
|
+
return task if found_task
|
112
|
+
res = task_where cond, task.tasks
|
113
|
+
return res if res
|
114
|
+
end
|
115
|
+
return nil
|
116
|
+
end
|
117
|
+
|
118
|
+
# Returns a flattened list of tasks in the GanttChart for iteration. Since +tasks+ is a tree,
|
119
|
+
# a user can use Array#select on +all_tasks+ instead.
|
120
|
+
#
|
121
|
+
# my_tasks = @gantt.all_tasks.select { |t| t.coordinators.include? me }
|
122
|
+
#
|
123
|
+
def all_tasks task_array = @tasks
|
124
|
+
found_tasks = []
|
125
|
+
task_array.each do |task|
|
126
|
+
found_tasks << task
|
127
|
+
res = all_tasks task.tasks
|
128
|
+
found_tasks << res
|
129
|
+
end
|
130
|
+
return [] if found_tasks.size == 0
|
131
|
+
return found_tasks.flatten.uniq
|
132
|
+
end
|
133
|
+
|
134
|
+
# Find a task by its GanttProject +id+ field.
|
135
|
+
def task_by_id id
|
136
|
+
task_where :id => id
|
137
|
+
end
|
138
|
+
|
139
|
+
# Generate the GanttProject XML for this GanttChart.
|
140
|
+
def to_xml
|
141
|
+
task_id = 0
|
142
|
+
resource_id = 0
|
143
|
+
|
144
|
+
@resources.each do |resource|
|
145
|
+
resource.instance_variable_set(:@id, resource_id += 1) unless resource.id
|
146
|
+
end
|
147
|
+
|
148
|
+
dependencies = { :starts_with => {}, :starts_after => {}, :finishes_with => {}, :finishes_before => {} }
|
149
|
+
all_tasks.each do |task|
|
150
|
+
task.instance_variable_set(:@id, task_id += 1) unless task.id
|
151
|
+
dependencies.each do |type,set|
|
152
|
+
task.send(type).each do |other_task|
|
153
|
+
set[other_task.id] = [] unless set[other_task.id]
|
154
|
+
set[other_task.id] << task.id
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
x = Builder::XmlMarkup.new :indent => 2
|
160
|
+
x.instruct! :xml, :version => '1.0', :encoding => 'UTF-8'
|
161
|
+
xml = x.project( :name => "Test XML") do
|
162
|
+
|
163
|
+
x.description ''
|
164
|
+
x.view( 'zooming-state' => 'default:7', 'id' => 'gantt-chart' )
|
165
|
+
x.view( 'id' => 'resource-table' ) do
|
166
|
+
x.field( :id => 0, :name => "Name", :width => 55, :order => 0)
|
167
|
+
x.field( :id => 1, :name => "Default role", :width => 44, :order => 1)
|
168
|
+
end
|
169
|
+
x.comment! ' '
|
170
|
+
|
171
|
+
x.calendars do
|
172
|
+
x.tag! "day-types" do
|
173
|
+
x.tag! "day-type", :id => 0
|
174
|
+
x.tag! "day-type", :id => 1
|
175
|
+
x.calendar( :id => 1, :name => :default) do
|
176
|
+
x.tag! "default-week", :sun => 0, :mon => 0, :tue => 0, :wed => 0, :thu => 0, :fri => 0, :sat => 0
|
177
|
+
x.tag! "overriden-day-types"
|
178
|
+
x.days
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
x.tasks( :color => "#8cb6ce" ) do
|
184
|
+
x.taskproperties do
|
185
|
+
x << <<-XML
|
186
|
+
<taskproperty id="tpd0" name="type" type="default" valuetype="icon"/>
|
187
|
+
<taskproperty id="tpd1" name="priority" type="default" valuetype="icon"/>
|
188
|
+
<taskproperty id="tpd2" name="info" type="default" valuetype="icon"/>
|
189
|
+
<taskproperty id="tpd3" name="name" type="default" valuetype="text"/>
|
190
|
+
<taskproperty id="tpd4" name="begindate" type="default" valuetype="date"/>
|
191
|
+
<taskproperty id="tpd5" name="enddate" type="default" valuetype="date"/>
|
192
|
+
<taskproperty id="tpd6" name="duration" type="default" valuetype="int"/>
|
193
|
+
<taskproperty id="tpd7" name="completion" type="default" valuetype="int"/>
|
194
|
+
<taskproperty id="tpd8" name="coordinator" type="default" valuetype="text"/>
|
195
|
+
<taskproperty id="tpd9" name="predecessorsr" type="default" valuetype="text"/>
|
196
|
+
XML
|
197
|
+
end
|
198
|
+
|
199
|
+
tasks.each do |t|
|
200
|
+
task_xml x, t, dependencies
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
x.resources do
|
206
|
+
resources.each do |resource|
|
207
|
+
x << resource.to_xml
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
x.allocations do
|
212
|
+
all_tasks.each do |task|
|
213
|
+
task.xml_coordinator_properties.each do |coordinator|
|
214
|
+
x.allocation(coordinator)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
x << <<-XML
|
220
|
+
<vacations/>
|
221
|
+
<taskdisplaycolumns>
|
222
|
+
<displaycolumn property-id="tpd3" order="0" width="172"/>
|
223
|
+
<displaycolumn property-id="tpd4" order="1" width="27"/>
|
224
|
+
<displaycolumn property-id="tpd5" order="2" width="26"/>
|
225
|
+
<displaycolumn property-id="tpd8" order="3" width="75"/>
|
226
|
+
</taskdisplaycolumns>
|
227
|
+
<previous/>
|
228
|
+
<roles roleset-name="Default"/>
|
229
|
+
XML
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
def task_xml xml, task, dependencies
|
236
|
+
xml.task(task.xml_properties) do
|
237
|
+
xml.notes { xml.cdata! task.notes } if task.notes
|
238
|
+
dependencies.each do |depend_type, values|
|
239
|
+
if values.include? task.id
|
240
|
+
values[task.id].each do |dependency|
|
241
|
+
xml.depend( :id => dependency, :type => REVERSE_DEPENDS[depend_type], :difference => 0, :hardness => "Strong" )
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
task.tasks.each { |t| task_xml xml, t, dependencies }
|
246
|
+
end
|
60
247
|
end
|
61
248
|
|
62
249
|
private
|
63
250
|
|
64
|
-
def
|
65
|
-
|
251
|
+
def add_subtasks_to_task task_xml, task_object
|
252
|
+
task_xml.children.select { |c| c.name == "task" }.each do |subtask_xml|
|
253
|
+
task_object.tasks << Task.new(subtask_xml)
|
254
|
+
task_object.tasks.each { |subtask_obj| add_subtasks_to_task subtask_xml, subtask_obj }
|
255
|
+
end
|
66
256
|
end
|
67
257
|
|
68
258
|
end
|
69
259
|
|
70
260
|
class Task
|
71
261
|
attr_accessor :name, :start, :duration, :end, :percent_complete, :coordinators, :priority
|
72
|
-
attr_accessor :starts_with, :starts_after, :finishes_with, :finishes_before
|
262
|
+
attr_accessor :starts_with, :starts_after, :finishes_with, :finishes_before, :color
|
263
|
+
attr_accessor :tasks, :notes, :link
|
73
264
|
|
74
265
|
attr_reader :id
|
75
266
|
|
76
267
|
def initialize t
|
77
|
-
@
|
268
|
+
@notes = nil
|
269
|
+
@starts_with, @starts_after, @finishes_with, @finishes_before, @tasks = [], [], [], [], []
|
78
270
|
if t.is_a? Hash
|
79
271
|
@name = t[:name]
|
80
272
|
elsif t.is_a? String
|
@@ -88,10 +280,20 @@ module Gantty
|
|
88
280
|
@end = @start + @duration
|
89
281
|
@percent_complete = t.attributes["complete"].to_i
|
90
282
|
@coordinators = []
|
283
|
+
@color = t.attributes["color"]
|
91
284
|
@id = t.attributes["id"].to_i
|
285
|
+
@link = (t.attributes.include?("webLink") ? t.attributes["webLink"] : nil)
|
286
|
+
t.children.select { |c| c.name == "notes" }.each do |note|
|
287
|
+
@notes = note.inner_text
|
288
|
+
end
|
92
289
|
end
|
93
290
|
end
|
94
291
|
|
292
|
+
def add_resource resource
|
293
|
+
(@coordinators ||= []) << resource
|
294
|
+
end
|
295
|
+
|
296
|
+
# Set the start date of the task. The duration is updated if an end date has already been specified.
|
95
297
|
def start= new_date
|
96
298
|
raise ArgumentError, "expected a DateTime" unless new_date.is_a? Date
|
97
299
|
raise ArgumentError, "start date cannot be past end date" if @end and new_date >= @end
|
@@ -99,6 +301,7 @@ module Gantty
|
|
99
301
|
@duration = (@end - @start).to_i if @end
|
100
302
|
end
|
101
303
|
|
304
|
+
# Set the end date of the task. The duration is updated if an end date has already been specified.
|
102
305
|
def end= new_date
|
103
306
|
raise ArgumentError, "expected a DateTime" unless new_date.is_a? Date
|
104
307
|
raise ArgumentError, "end date cannot be before start date" if @start and new_date <= @start
|
@@ -106,6 +309,8 @@ module Gantty
|
|
106
309
|
@duration = (@end - @start).to_i if @start
|
107
310
|
end
|
108
311
|
|
312
|
+
# Set the duration of the task. If a start date has been specified, the end date will be set to (start + duration).
|
313
|
+
# If a start date has not been specified, today is used.
|
109
314
|
def duration= new_duration
|
110
315
|
raise ArgumentError, "expected a number of days" unless new_duration.is_a? Fixnum
|
111
316
|
raise ArgumentError, "expected a positive day count" if new_duration < 0
|
@@ -114,12 +319,29 @@ module Gantty
|
|
114
319
|
@end = @start + new_duration
|
115
320
|
end
|
116
321
|
|
322
|
+
# Set the percentage of the task that has been completed. Only accepts whole integers, since GanttProject does too.
|
117
323
|
def percent_complete= new_percent
|
118
324
|
raise ArgumentError, "percent complete must be a number" unless new_percent.is_a? Fixnum
|
119
325
|
raise ArgumentError, "percent complete must be between 0 and 100" if new_percent < 0 or new_percent > 100
|
120
326
|
@percent_complete = new_percent
|
121
327
|
end
|
122
328
|
|
329
|
+
def xml_properties
|
330
|
+
properties = { :id => id, :name => name, :color => color, :meeting => false,
|
331
|
+
:start => start.strftime("%Y-%m-%d"), :duration => duration, :complete => percent_complete, :priority => PRIORITY[priority], :expand => false }
|
332
|
+
properties.merge!( :webLink => @link ) if @link
|
333
|
+
return properties
|
334
|
+
end
|
335
|
+
|
336
|
+
def xml_coordinator_properties
|
337
|
+
res = []
|
338
|
+
return res unless @coordinators
|
339
|
+
@coordinators.each do |coordinator|
|
340
|
+
res << {"task-id" => id, "resource-id" => coordinator.id, :function => "Default:0", :responsible => true, :load => 100.0 }
|
341
|
+
end
|
342
|
+
return res
|
343
|
+
end
|
344
|
+
|
123
345
|
#
|
124
346
|
# If Task B has predecessor Task A with relationship Finish->Start, task_b.before.include? task_a
|
125
347
|
# <task id="#{task_a.id}"...><depend id="#{task_b.id}" type="2" difference="1" hardness="Rubber"/></task>
|
@@ -144,7 +366,7 @@ module Gantty
|
|
144
366
|
def add_finishes_before t
|
145
367
|
@finishes_before << t
|
146
368
|
end
|
147
|
-
|
369
|
+
|
148
370
|
end
|
149
371
|
|
150
372
|
class Resource
|
@@ -152,10 +374,22 @@ module Gantty
|
|
152
374
|
attr_reader :id
|
153
375
|
|
154
376
|
def initialize r
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
377
|
+
if r.is_a? Hash
|
378
|
+
@name = r[:name]
|
379
|
+
elsif r.is_a? String
|
380
|
+
raise ArgumentError, "name cannot be blank" if r.length == 0
|
381
|
+
@name = r
|
382
|
+
else
|
383
|
+
@name = r.attributes["name"]
|
384
|
+
@phone = r.attributes["phone"]
|
385
|
+
@email = r.attributes["contacts"]
|
386
|
+
@id = r.attributes["id"].to_i
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
def to_xml
|
391
|
+
x = Builder::XmlMarkup.new :indent => 2
|
392
|
+
xml = x.resource( { :id => id, :name => name, :phone => phone, :contacts => email, :function=> "Default:0" } )
|
159
393
|
end
|
160
394
|
|
161
395
|
end
|
data/spec/gantty_spec.rb
CHANGED
data/spec/task_spec.rb
CHANGED
@@ -4,8 +4,8 @@ describe "Task" do
|
|
4
4
|
|
5
5
|
before do
|
6
6
|
@gantt = Gantty::Open GANTT_CHART
|
7
|
-
@task = @gantt.
|
8
|
-
@team_task = @gantt.
|
7
|
+
@task = @gantt.all_tasks.first
|
8
|
+
@team_task = @gantt.task_where :id => 12
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should have a name" do
|
@@ -77,32 +77,43 @@ describe "Task" do
|
|
77
77
|
lambda { task = Gantty::Task.new :name => "This is the task name" }.should_not raise_error
|
78
78
|
end
|
79
79
|
|
80
|
+
it "should include all subtasks" do
|
81
|
+
@head = @gantt.task_where :name => "Project Planning"
|
82
|
+
@head.tasks.size.should == 2
|
83
|
+
|
84
|
+
@gantt.task_where( :name => "Research" ).tasks.size.should == 5
|
85
|
+
@gantt.task_where( :name => "Website" ).tasks.size.should == 0
|
86
|
+
end
|
87
|
+
|
80
88
|
# Start-Start: 1 => #starts_with
|
81
89
|
# Finish-Start: 2 => #starts_after
|
82
90
|
# Finish-Finish: 3 => #finishes_with
|
83
91
|
# Start-Finish: 4 => #finishes_before
|
84
92
|
|
85
93
|
it "should return the Start-Start tasks of itself" do
|
86
|
-
@pred_task = @gantt.
|
94
|
+
@pred_task = @gantt.task_where :id => 13
|
87
95
|
@pred_task.name.should == "Acceptance Test Plan"
|
88
96
|
@pred_task.starts_with.size.should == 1
|
89
97
|
@pred_task.starts_with.first.name.should == "Requirements Document"
|
90
98
|
end
|
91
99
|
|
92
100
|
it "should return the Finish-Start tasks of itself" do
|
93
|
-
@pred_task = @gantt.
|
101
|
+
@pred_task = @gantt.task_where :id => 13
|
94
102
|
@pred_task.name.should == "Acceptance Test Plan"
|
95
103
|
@pred_task.starts_after.size.should == 1
|
96
104
|
@pred_task.starts_after.first.name.should == "Integration Test Plan"
|
97
105
|
end
|
98
106
|
|
99
107
|
it "should return the Start-Finish tasks of itself" do
|
100
|
-
@pred_task = @gantt.
|
108
|
+
@pred_task = @gantt.task_where :id => 14
|
101
109
|
@pred_task.name.should == "Design Document"
|
102
110
|
@pred_task.finishes_before.size.should == 1
|
103
111
|
@pred_task.finishes_before.first.name.should == "Acceptance Test Plan"
|
104
112
|
end
|
105
113
|
|
114
|
+
it "should allow the dependencies to be changed"
|
115
|
+
it "should allow the specification of dependency delay and hardness"
|
116
|
+
|
106
117
|
it "should return the percentage completed" do
|
107
118
|
@task.percent_complete.should == 13
|
108
119
|
end
|
@@ -112,6 +123,10 @@ describe "Task" do
|
|
112
123
|
@task.percent_complete.should == 90
|
113
124
|
end
|
114
125
|
|
126
|
+
it "should not allow fractional percent completions" do
|
127
|
+
lambda { task.percent_complete = 24.4 }.should raise_error
|
128
|
+
end
|
129
|
+
|
115
130
|
it "should ensure the percentage completed is a number" do
|
116
131
|
lambda { task.percent_complete = "blah" }.should raise_error
|
117
132
|
end
|
data/spec/test_gantt_project.gan
CHANGED
@@ -1,87 +1,87 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<project name="ClementineGantt" company="" webLink="" view-date="2008-08-17" view-index="0" gantt-divider-location="652" resource-divider-location="301" version="2.0">
|
3
|
-
<description
|
4
|
-
<view zooming-state="default:7" id="gantt-chart"/>
|
5
|
-
<view id="resource-table">
|
6
|
-
<field id="0" name="Name" width="55" order="0"/>
|
7
|
-
<field id="1" name="Default role" width="44" order="1"/>
|
8
|
-
</view>
|
9
|
-
<!-- -->
|
10
|
-
<calendars>
|
11
|
-
<day-types>
|
12
|
-
<day-type id="0"/>
|
13
|
-
<day-type id="1"/>
|
14
|
-
<calendar id="1" name="default">
|
15
|
-
<default-week sun="0" mon="0" tue="0" wed="0" thu="0" fri="0" sat="0"/>
|
16
|
-
<overriden-day-types/>
|
17
|
-
<days/>
|
18
|
-
</calendar>
|
19
|
-
</day-types>
|
20
|
-
</calendars>
|
21
|
-
<tasks color="#8cb6ce">
|
22
|
-
<taskproperties>
|
23
|
-
<taskproperty id="tpd0" name="type" type="default" valuetype="icon"/>
|
24
|
-
<taskproperty id="tpd1" name="priority" type="default" valuetype="icon"/>
|
25
|
-
<taskproperty id="tpd2" name="info" type="default" valuetype="icon"/>
|
26
|
-
<taskproperty id="tpd3" name="name" type="default" valuetype="text"/>
|
27
|
-
<taskproperty id="tpd4" name="begindate" type="default" valuetype="date"/>
|
28
|
-
<taskproperty id="tpd5" name="enddate" type="default" valuetype="date"/>
|
29
|
-
<taskproperty id="tpd6" name="duration" type="default" valuetype="int"/>
|
30
|
-
<taskproperty id="tpd7" name="completion" type="default" valuetype="int"/>
|
31
|
-
<taskproperty id="tpd8" name="coordinator" type="default" valuetype="text"/>
|
32
|
-
<taskproperty id="tpd9" name="predecessorsr" type="default" valuetype="text"/>
|
33
|
-
</taskproperties>
|
34
|
-
<task id="0" name="Project Planning" color="#8cb6ce" meeting="false" start="2008-10-14" duration="161" complete="13" priority="2" expand="true">
|
35
|
-
<task id="1" name="Research" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="47" priority="1" expand="false">
|
36
|
-
<task id="2" name="Prior Art" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="0" priority="1" expand="true"/>
|
37
|
-
<task id="3" name="Focus Groups" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="0" priority="1" expand="true">
|
38
|
-
<notes><![CDATA[investigate how to get this into the hands of a student in a game class during term 2 or 3]]></notes>
|
39
|
-
</task>
|
40
|
-
<task id="4" name="Marketing / Branding" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="0" priority="1" expand="true"/>
|
41
|
-
<task id="5" name="Logos / Graphical Design" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="0" priority="1" expand="true"/>
|
42
|
-
<task id="6" name="Wii Homebrew" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="75" priority="1" expand="true"/>
|
43
|
-
</task>
|
44
|
-
<task id="10" name="Website" color="#8cb6ce" meeting="false" start="2008-11-03" duration="141" complete="8" priority="1" expand="true"/>
|
45
|
-
</task>
|
46
|
-
<task id="11" name="Project Design" color="#8cb6ce" meeting="false" start="2008-11-03" duration="107" complete="1" priority="1" expand="true">
|
47
|
-
<task id="12" name="Requirements Document" color="#ff3333" meeting="false" start="2008-11-03" duration="16" complete="7" priority="1" expand="true">
|
48
|
-
<depend id="13" type="1" difference="1" hardness="Strong"/>
|
49
|
-
</task>
|
50
|
-
<task id="13" name="Acceptance Test Plan" color="#ff3333" meeting="false" start="2009-02-06" duration="12" complete="0" priority="1" expand="true">
|
51
|
-
<depend id="14" type="4" difference="0" hardness="Strong"/>
|
52
|
-
</task>
|
53
|
-
<task id="14" name="Design Document" color="#ff3333" meeting="false" start="2008-12-23" duration="45" complete="0" priority="1" expand="true"/>
|
54
|
-
<task id="15" name="Integration Test Plan" color="#ff3333" meeting="false" start="2009-01-26" duration="11" complete="0" priority="1" expand="true">
|
55
|
-
<depend id="13" type="2" difference="0" hardness="Strong"/>
|
56
|
-
</task>
|
57
|
-
</task>
|
58
|
-
</tasks>
|
59
|
-
<resources>
|
60
|
-
<resource id="6" name="Adam Alpha" function="Default:1" contacts="adam.alpha@gmail.com" phone="555-555-0123"/>
|
61
|
-
<resource id="7" name="Bob Beta" function="Default:0" contacts="bob.beta@gmail.com" phone="555-555-1234"/>
|
62
|
-
<resource id="8" name="Dave Delta" function="Default:0" contacts="dave.delta@gmail.com" phone="555-555-2345"/>
|
63
|
-
<resource id="9" name="Ed Epsilon" function="Default:0" contacts="ed.epsilon@gmail.com" phone="555-555-3456"/>
|
64
|
-
</resources>
|
65
|
-
<allocations>
|
66
|
-
<allocation task-id="2" resource-id="8" function="Default:0" responsible="true" load="100.0"/>
|
67
|
-
<allocation task-id="4" resource-id="7" function="Default:0" responsible="true" load="100.0"/>
|
68
|
-
<allocation task-id="5" resource-id="9" function="Default:0" responsible="true" load="100.0"/>
|
69
|
-
<allocation task-id="6" resource-id="9" function="Default:0" responsible="true" load="100.0"/>
|
70
|
-
<allocation task-id="10" resource-id="7" function="Default:0" responsible="true" load="100.0"/>
|
71
|
-
<allocation task-id="10" resource-id="9" function="Default:0" responsible="false" load="100.0"/>
|
72
|
-
<allocation task-id="12" resource-id="7" function="Default:0" responsible="true" load="100.0"/>
|
73
|
-
<allocation task-id="12" resource-id="6" function="Default:1" responsible="true" load="100.0"/>
|
74
|
-
<allocation task-id="13" resource-id="7" function="Default:0" responsible="true" load="100.0"/>
|
75
|
-
<allocation task-id="14" resource-id="6" function="Default:1" responsible="true" load="100.0"/>
|
76
|
-
<allocation task-id="15" resource-id="7" function="Default:0" responsible="true" load="100.0"/>
|
77
|
-
</allocations>
|
78
|
-
<vacations/>
|
79
|
-
<taskdisplaycolumns>
|
80
|
-
<displaycolumn property-id="tpd3" order="0" width="172"/>
|
81
|
-
<displaycolumn property-id="tpd4" order="1" width="27"/>
|
82
|
-
<displaycolumn property-id="tpd5" order="2" width="26"/>
|
83
|
-
<displaycolumn property-id="tpd8" order="3" width="75"/>
|
84
|
-
</taskdisplaycolumns>
|
85
|
-
<previous/>
|
86
|
-
<roles roleset-name="Default"/>
|
3
|
+
<description/>
|
4
|
+
<view zooming-state="default:7" id="gantt-chart"/>
|
5
|
+
<view id="resource-table">
|
6
|
+
<field id="0" name="Name" width="55" order="0"/>
|
7
|
+
<field id="1" name="Default role" width="44" order="1"/>
|
8
|
+
</view>
|
9
|
+
<!-- -->
|
10
|
+
<calendars>
|
11
|
+
<day-types>
|
12
|
+
<day-type id="0"/>
|
13
|
+
<day-type id="1"/>
|
14
|
+
<calendar id="1" name="default">
|
15
|
+
<default-week sun="0" mon="0" tue="0" wed="0" thu="0" fri="0" sat="0"/>
|
16
|
+
<overriden-day-types/>
|
17
|
+
<days/>
|
18
|
+
</calendar>
|
19
|
+
</day-types>
|
20
|
+
</calendars>
|
21
|
+
<tasks color="#8cb6ce">
|
22
|
+
<taskproperties>
|
23
|
+
<taskproperty id="tpd0" name="type" type="default" valuetype="icon"/>
|
24
|
+
<taskproperty id="tpd1" name="priority" type="default" valuetype="icon"/>
|
25
|
+
<taskproperty id="tpd2" name="info" type="default" valuetype="icon"/>
|
26
|
+
<taskproperty id="tpd3" name="name" type="default" valuetype="text"/>
|
27
|
+
<taskproperty id="tpd4" name="begindate" type="default" valuetype="date"/>
|
28
|
+
<taskproperty id="tpd5" name="enddate" type="default" valuetype="date"/>
|
29
|
+
<taskproperty id="tpd6" name="duration" type="default" valuetype="int"/>
|
30
|
+
<taskproperty id="tpd7" name="completion" type="default" valuetype="int"/>
|
31
|
+
<taskproperty id="tpd8" name="coordinator" type="default" valuetype="text"/>
|
32
|
+
<taskproperty id="tpd9" name="predecessorsr" type="default" valuetype="text"/>
|
33
|
+
</taskproperties>
|
34
|
+
<task id="0" name="Project Planning" color="#8cb6ce" meeting="false" start="2008-10-14" duration="161" complete="13" priority="2" expand="true">
|
35
|
+
<task id="1" name="Research" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="47" priority="1" expand="false">
|
36
|
+
<task id="2" name="Prior Art" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="0" priority="1" expand="true"/>
|
37
|
+
<task id="3" name="Focus Groups" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="0" priority="1" expand="true">
|
38
|
+
<notes><![CDATA[investigate how to get this into the hands of a student in a game class during term 2 or 3]]></notes>
|
39
|
+
</task>
|
40
|
+
<task id="4" name="Marketing / Branding" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="0" priority="1" expand="true"/>
|
41
|
+
<task id="5" name="Logos / Graphical Design" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="0" priority="1" expand="true"/>
|
42
|
+
<task id="6" name="Wii Homebrew" color="#8cb6ce" meeting="false" start="2008-10-14" duration="6" complete="75" priority="1" expand="true"/>
|
43
|
+
</task>
|
44
|
+
<task id="10" name="Website" color="#8cb6ce" meeting="false" start="2008-11-03" duration="141" complete="8" priority="1" expand="true"/>
|
45
|
+
</task>
|
46
|
+
<task id="11" name="Project Design" color="#8cb6ce" meeting="false" start="2008-11-03" duration="107" complete="1" priority="1" expand="true">
|
47
|
+
<task id="12" name="Requirements Document" color="#ff3333" meeting="false" start="2008-11-03" duration="16" complete="7" priority="1" expand="true">
|
48
|
+
<depend id="13" type="1" difference="1" hardness="Strong"/>
|
49
|
+
</task>
|
50
|
+
<task id="13" name="Acceptance Test Plan" color="#ff3333" meeting="false" start="2009-02-06" duration="12" complete="0" priority="1" expand="true">
|
51
|
+
<depend id="14" type="4" difference="0" hardness="Strong"/>
|
52
|
+
</task>
|
53
|
+
<task id="14" name="Design Document" color="#ff3333" meeting="false" start="2008-12-23" duration="45" complete="0" priority="1" expand="true"/>
|
54
|
+
<task id="15" name="Integration Test Plan" color="#ff3333" meeting="false" start="2009-01-26" duration="11" complete="0" priority="1" expand="true">
|
55
|
+
<depend id="13" type="2" difference="0" hardness="Strong"/>
|
56
|
+
</task>
|
57
|
+
</task>
|
58
|
+
</tasks>
|
59
|
+
<resources>
|
60
|
+
<resource id="6" name="Adam Alpha" function="Default:1" contacts="adam.alpha@gmail.com" phone="555-555-0123"/>
|
61
|
+
<resource id="7" name="Bob Beta" function="Default:0" contacts="bob.beta@gmail.com" phone="555-555-1234"/>
|
62
|
+
<resource id="8" name="Dave Delta" function="Default:0" contacts="dave.delta@gmail.com" phone="555-555-2345"/>
|
63
|
+
<resource id="9" name="Ed Epsilon" function="Default:0" contacts="ed.epsilon@gmail.com" phone="555-555-3456"/>
|
64
|
+
</resources>
|
65
|
+
<allocations>
|
66
|
+
<allocation task-id="2" resource-id="8" function="Default:0" responsible="true" load="100.0"/>
|
67
|
+
<allocation task-id="4" resource-id="7" function="Default:0" responsible="true" load="100.0"/>
|
68
|
+
<allocation task-id="5" resource-id="9" function="Default:0" responsible="true" load="100.0"/>
|
69
|
+
<allocation task-id="6" resource-id="9" function="Default:0" responsible="true" load="100.0"/>
|
70
|
+
<allocation task-id="10" resource-id="7" function="Default:0" responsible="true" load="100.0"/>
|
71
|
+
<allocation task-id="10" resource-id="9" function="Default:0" responsible="false" load="100.0"/>
|
72
|
+
<allocation task-id="12" resource-id="7" function="Default:0" responsible="true" load="100.0"/>
|
73
|
+
<allocation task-id="12" resource-id="6" function="Default:1" responsible="true" load="100.0"/>
|
74
|
+
<allocation task-id="13" resource-id="7" function="Default:0" responsible="true" load="100.0"/>
|
75
|
+
<allocation task-id="14" resource-id="6" function="Default:1" responsible="true" load="100.0"/>
|
76
|
+
<allocation task-id="15" resource-id="7" function="Default:0" responsible="true" load="100.0"/>
|
77
|
+
</allocations>
|
78
|
+
<vacations/>
|
79
|
+
<taskdisplaycolumns>
|
80
|
+
<displaycolumn property-id="tpd3" order="0" width="172"/>
|
81
|
+
<displaycolumn property-id="tpd4" order="1" width="27"/>
|
82
|
+
<displaycolumn property-id="tpd5" order="2" width="26"/>
|
83
|
+
<displaycolumn property-id="tpd8" order="3" width="75"/>
|
84
|
+
</taskdisplaycolumns>
|
85
|
+
<previous/>
|
86
|
+
<roles roleset-name="Default"/>
|
87
87
|
</project>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ardekantur-gantty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ardekantur
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-11-
|
12
|
+
date: 2008-11-22 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 1.0.2
|
23
23
|
version:
|
24
|
-
description: read ( + write
|
24
|
+
description: read ( + write ) gantt project xml files
|
25
25
|
email: greystone@ardekantur.com
|
26
26
|
executables: []
|
27
27
|
|
@@ -39,7 +39,7 @@ files:
|
|
39
39
|
- spec/spec_helper.rb
|
40
40
|
- spec/task_spec.rb
|
41
41
|
- spec/test_gantt_project.gan
|
42
|
-
has_rdoc:
|
42
|
+
has_rdoc: true
|
43
43
|
homepage: http://github.com/ardekantur/gantty
|
44
44
|
post_install_message:
|
45
45
|
rdoc_options: []
|
@@ -64,7 +64,7 @@ rubyforge_project:
|
|
64
64
|
rubygems_version: 1.2.0
|
65
65
|
signing_key:
|
66
66
|
specification_version: 2
|
67
|
-
summary: read ( + write
|
67
|
+
summary: read ( + write ) gantt project xml files
|
68
68
|
test_files:
|
69
69
|
- spec/gantty_spec.rb
|
70
70
|
- spec/resource_spec.rb
|