Class: TaskJuggler::GanttChart
- Includes:
- HTMLGraphics
- Defined in:
- lib/taskjuggler/reports/GanttChart.rb
Overview
This class represents an abstract (output format independent) Gantt chart. It provides generator functions that can transform the abstract form into formats such as HTML or SVG. The appearance of the chart depend on 3 variable: the report period, the geometrical width and the scale. The report period is always provided by the user. In addition the width or the scale can be provided. The non-provided value will then be calculated. So after the object has been created, the user must call generateByWidth or generateByResolution.
Constant Summary collapse
- SCROLLBARHEIGHT =
The height in pixels of a horizontal scrollbar on an HTML page. This value should be large enough to work for all browsers.
20
Instance Attribute Summary collapse
-
#end ⇒ Object
readonly
Returns the value of attribute end.
-
#header ⇒ Object
readonly
Returns the value of attribute header.
-
#markdate ⇒ Object
readonly
Returns the value of attribute markdate.
-
#now ⇒ Object
readonly
Returns the value of attribute now.
-
#scale ⇒ Object
readonly
Returns the value of attribute scale.
-
#scales ⇒ Object
readonly
Returns the value of attribute scales.
-
#start ⇒ Object
readonly
Returns the value of attribute start.
-
#table ⇒ Object
readonly
Returns the value of attribute table.
-
#viewWidth ⇒ Object
writeonly
Sets the attribute viewWidth.
-
#weekStartsMonday ⇒ Object
readonly
Returns the value of attribute weekStartsMonday.
-
#width ⇒ Object
readonly
Returns the value of attribute width.
Instance Method Summary collapse
-
#addLine(line) ⇒ Object
This is not a user callable function.
-
#addTask(task, line) ⇒ Object
Add a primary tasks line to the dictonary.
-
#dateToX(date) ⇒ Object
Utility function that convers a date to the corresponding X-position in the Gantt chart.
-
#generateByScale(periodStart, periodEnd, scaleName) ⇒ Object
Generate the actual chart data based on the report interval specified by periodStart and periodEnd as well as the name of the requested scale to be used.
- #generateByWidth(periodStart, periodEnd, width) ⇒ Object
-
#hasScrollbar? ⇒ Boolean
Returns true if the chart includes a scrollbar.
-
#initialize(now, weekStartsMonday, columnDef, table = nil, markdate = nil) ⇒ GanttChart
constructor
Create the GanttChart object, but don’t do much right now.
-
#to_csv(csv, startColumn) ⇒ Object
This is a noop function.
-
#to_html ⇒ Object
Convert the chart into an HTML representation.
Methods included from HTMLGraphics
#arrowHeadToHTML, #diamondToHTML, #jagToHTML, #lineToHTML, #rectToHTML
Constructor Details
#initialize(now, weekStartsMonday, columnDef, table = nil, markdate = nil) ⇒ GanttChart
Create the GanttChart object, but don’t do much right now. We still need more information about the chart before we can actually generate it. now is the date that should be used as current date. weekStartsMonday is true if the weeks should start on Mondays instead of Sundays. table is a reference to the TableReport that the chart is part of.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 46 def initialize(now, weekStartsMonday, columnDef, table = nil, markdate = nil) # The start and end dates of the reported interval. @start = nil @end = nil @now = now @columnDef = columnDef @table = table @markdate = markdate # This defines the possible horizontal scales that the Gantt chart can # have. The scales differ in their resolution and the amount of detail # that is displayed. A scale is defined by its name. The _name_ must be # unique and can be used to select the scale. The _stepSize_ defines the # width of a scale step in pixels. The _stepsToFunc_ is a TjTime method # that determines the number of steps between 2 dates. _minTimeOff_ # defines the minimum required length of an time-off interval that is # displayed in this scale. @@scales = [ { 'name' => 'hour', 'stepSize' => 20, 'stepsToFunc' => :hoursTo, 'minTimeOff' => 5 * 60 }, { 'name' => 'day', 'stepSize' => 20, 'stepsToFunc' => :daysTo, 'minTimeOff' => 6 * 60 * 60 }, { 'name' => 'week', 'stepSize' => 20, 'stepsToFunc' => :weeksTo, 'minTimeOff' => 24 * 60 * 60 }, { 'name' => 'month', 'stepSize' => 35, 'stepsToFunc' => :monthsTo, 'minTimeOff' => 5 * 24 * 60 * 60 }, { 'name' => 'quarter', 'stepSize' => 28, 'stepsToFunc' => :quartersTo, 'minTimeOff' => -1 }, { 'name' => 'year', 'stepSize' => 20, 'stepsToFunc' => :yearsTo, 'minTimeOff' => -1 } ] # This points to one of the scales above and marks the current scale. @scale = nil # The height of the chart (without the header) @height = 0 # The width of the chart in pixels. @width = 0 # The width of the view that the chart is presented in. If it's nil, the # view will be adapted to the width of the chart. @viewWidth = nil # True of the week starts on a Monday. @weekStartsMonday = weekStartsMonday # Reference to the GanttHeader object that models the chart header. @header = nil # The GanttLine objects that model the lines of the chart. @lines = [] # The router for dependency lines. @router = nil # This dictionary stores primary task lines indexed by their task. To # handle multiple scenarios, the dictionary stored the lines in an Array. # This is used to generate dependency arrows. @tasks = {} # This is a list of the dependency lines. Each entry is an Array of [x, y] # coordinate pairs. @depArrows = [] # This is the list of arrow heads used for the dependency arrows. It # contains an Array of [ x, y ] coordinates that mark the tip of the # arrow. @arrowHeads = [] end |
Instance Attribute Details
#end ⇒ Object (readonly)
Returns the value of attribute end.
37 38 39 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 37 def end @end end |
#header ⇒ Object (readonly)
Returns the value of attribute header.
37 38 39 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 37 def header @header end |
#markdate ⇒ Object (readonly)
Returns the value of attribute markdate.
37 38 39 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 37 def markdate @markdate end |
#now ⇒ Object (readonly)
Returns the value of attribute now.
37 38 39 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 37 def now @now end |
#scale ⇒ Object (readonly)
Returns the value of attribute scale.
37 38 39 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 37 def scale @scale end |
#scales ⇒ Object (readonly)
Returns the value of attribute scales.
37 38 39 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 37 def scales @scales end |
#start ⇒ Object (readonly)
Returns the value of attribute start.
37 38 39 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 37 def start @start end |
#table ⇒ Object (readonly)
Returns the value of attribute table.
37 38 39 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 37 def table @table end |
#viewWidth=(value) ⇒ Object (writeonly)
Sets the attribute viewWidth
39 40 41 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 39 def viewWidth=(value) @viewWidth = value end |
#weekStartsMonday ⇒ Object (readonly)
Returns the value of attribute weekStartsMonday.
37 38 39 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 37 def weekStartsMonday @weekStartsMonday end |
#width ⇒ Object (readonly)
Returns the value of attribute width.
37 38 39 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 37 def width @width end |
Instance Method Details
#addLine(line) ⇒ Object
This is not a user callable function. It’s only meant for use within the library.
217 218 219 220 221 222 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 217 def addLine(line) #:nodoc: if @scale.nil? raise "generateByScale or generateByWidth must be called first" end @lines << line end |
#addTask(task, line) ⇒ Object
Add a primary tasks line to the dictonary. task is a reference to the Task object and line is the corresponding primary ReportTableLine.
110 111 112 113 114 115 116 117 118 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 110 def addTask(task, line) if @tasks.include?(task) # Append the line to the existing lines. @tasks[task] << line else # Add a new Array for this tasks and store the first line. @tasks[task] = [ line ] end end |
#dateToX(date) ⇒ Object
Utility function that convers a date to the corresponding X-position in the Gantt chart.
211 212 213 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 211 def dateToX(date) ((@width / (@end - @start)) * (date - @start)).to_i end |
#generateByScale(periodStart, periodEnd, scaleName) ⇒ Object
Generate the actual chart data based on the report interval specified by periodStart and periodEnd as well as the name of the requested scale to be used. This function (or generateByWidth) must be called before any GanttLine objects are created for this chart.
132 133 134 135 136 137 138 139 140 141 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 132 def generateByScale(periodStart, periodEnd, scaleName) @start = periodStart @end = periodEnd @scale = scaleByName(scaleName) @stepSize = @scale['stepSize'] steps = @start.send(@scale['stepsToFunc'], @end) @width = @stepSize * steps @header = GanttHeader.new(@columnDef, self) end |
#generateByWidth(periodStart, periodEnd, width) ⇒ Object
121 122 123 124 125 126 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 121 def generateByWidth(periodStart, periodEnd, width) @start = periodStart @end = periodEnd @width = width # TODO end |
#hasScrollbar? ⇒ Boolean
Returns true if the chart includes a scrollbar.
225 226 227 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 225 def @viewWidth && (@viewWidth < @width) end |
#to_csv(csv, startColumn) ⇒ Object
This is a noop function.
204 205 206 207 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 204 def to_csv(csv, startColumn) # Can't put a Gantt chart into a CSV file. 0 end |
#to_html ⇒ Object
Convert the chart into an HTML representation.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/taskjuggler/reports/GanttChart.rb', line 144 def to_html completeChart # The chart is rendered into a cell that extends over the full height of # the table. No other cells for this column will be generated. In case # there is a scrollbar, the table will have an extra line to hold the # scrollbar. td = XMLElement.new('td', 'rowspan' => "#{2 + @lines.length + ( ? 1 : 0)}", 'style' => 'padding:0px; vertical-align:top;') # Now we generate two 'div's nested into each other. The first div is the # view. It may contain a scrollbar if the second div is wider than the # first one. In case we need a scrollbar The outer div is # SCROLLBARHEIGHT pixels heigher to hold the scrollbar. Unfortunately # this must be a hardcoded value even though the height of the scrollbar # varies from system to system. This value should be good enough for # most systems. td << (scrollDiv = XMLElement.new('div', 'class' => 'tabback', 'style' => 'position:relative; ' + "overflow:auto; " + "width:#{ ? @viewWidth : @width}px; " + "height:#{@height + ( ? SCROLLBARHEIGHT : 0)}px;")) scrollDiv << (div = XMLElement.new('div', 'style' => "margin:0px; padding:0px; " + "position:absolute; overflow:hidden; " + "top:0px; left:0px; " + "width:#{@width}px; " + "height:#{@height}px; " + "font-size:10px;")) # Add the header. div << @header.to_html # These are the lines of the chart. @lines.each do |line| div << line.to_html end # This is used for debugging and testing only. #div << @router.to_html # Render the dependency lines. @depArrows.each do |arrow| xx = yy = nil arrow.each do |x, y| if xx div << lineToHTML(xx, yy, x, y, 'depline') end xx = x yy = y end end # And the corresponsing arrow heads. @arrowHeads.each do |x, y| div << arrowHeadToHTML(x, y) end td end |