class TaskJuggler::GanttLoadStack

The GanttLoadStack is a simple stack diagram that shows the relative shares of the values. The stack is always normed to the line height.

Public Class Methods

new(line, x, w, values, categories) click to toggle source

Create a GanttLoadStack object based on the following information: line is a reference to the GanttLine. x is the left edge in chart coordinates and w is the stack width. values are the values to be displayed and categories determines the color for each of the values.

# File lib/taskjuggler/reports/GanttLoadStack.rb, line 28
def initialize(line, x, w, values, categories)
  @line = line
  @lineHeight = line.height
  @x = x
  @y = @line.y
  @w = w <= 0 ? 1 : w
  @drawFrame = false
  if values.length != categories.length
    raise "Values and categories must have the same number of entries!"
  end
  @categories = categories
  i = 0
  @categories.each do |cat|
    if cat.nil? && values[i] > 0
      @drawFrame = true
      break
    end
    i += 1
  end

  # Convert the values to chart Y coordinates and store them in yLevels.
  sum = 0
  values.each { |v| sum += v }
  # If the sum is 0, all yLevels values must be 0 as well.
  if sum == 0
    @yLevels = nil
    @drawFrame = true
  else
    @yLevels = []
    values.each do |v|
      # We leave 1 pixel to the top and bottom of the line and need 1 pixel
      # for the frame.
      @yLevels << (@lineHeight - 4) * v / sum
    end
  end
end

Public Instance Methods

addBlockedZones(router) click to toggle source
# File lib/taskjuggler/reports/GanttLoadStack.rb, line 65
def addBlockedZones(router)
  # Horizontal block
  router.addZone(@x - 2, @y, @w + 4, @lineHeight, true, false)
end
to_html() click to toggle source

Convert the abstact representation of the GanttLoadStack into HTML elements.

# File lib/taskjuggler/reports/GanttLoadStack.rb, line 72
def to_html
  # Draw nothing if all values are 0.
  return nil unless @yLevels

  html = []
  # Draw a background rectable to create a frame. In case the frame is not
  # fully filled by the stack, we need to draw a real frame to keep the
  # background.
  if @drawFrame
    # Top frame line
    html << @line.lineToHTML(@x, 1, @x + @w - 1, 1, 'loadstackframe')
    # Bottom frame line
    html << @line.lineToHTML(@x, @lineHeight - 2, @x + @w - 1,
                             @lineHeight - 2, 'loadstackframe')
    # Left frame line
    html << @line.lineToHTML(@x, 1, @x, @lineHeight - 2, 'loadstackframe')
    # Right frame line
    html << @line.lineToHTML(@x + @w - 1, 1, @x + @w - 1, @lineHeight - 2,
                             'loadstackframe')
  else
    html << @line.rectToHTML(@x, 1, @w, @lineHeight - 2,
                             'loadstackframe')
  end

  yPos = 2
  # Than draw the slighly narrower bars as a pile ontop of it.
  (@yLevels.length - 1).downto(0) do |i|
    next if @yLevels[i] <= 0
    if @categories[i]
      html << @line.rectToHTML(@x + 1, yPos.to_i, @w - 2,
                               (yPos + @yLevels[i]).to_i - yPos.to_i,
                               @categories[i])
    end
    yPos += @yLevels[i]
  end

  html
end