class TaskJuggler::TraceReport
The trace report is used to periodically snapshot a specific list of property attributes and add them to a CSV file.
Public Class Methods
new(report)
click to toggle source
Create a new object and set some default values.
Calls superclass method
TaskJuggler::ReportBase::new
# File lib/taskjuggler/reports/TraceReport.rb, line 29 def initialize(report) super @table = nil end
Public Instance Methods
generateIntermediateFormat()
click to toggle source
Generate the table in the intermediate format.
Calls superclass method
TaskJuggler::ReportBase#generateIntermediateFormat
# File lib/taskjuggler/reports/TraceReport.rb, line 35 def generateIntermediateFormat super queryAttrs = { 'project' => @project, 'scopeProperty' => nil, 'loadUnit' => a('loadUnit'), 'numberFormat' => a('numberFormat'), # We use a hardcoded %Y-%m-%d format for tracereports. 'timeFormat' => "%Y-%m-%d", 'currencyFormat' => a('currencyFormat'), 'start' => a('start'), 'end' => a('end'), 'hideJournalEntry' => a('hideJournalEntry'), 'journalMode' => a('journalMode'), 'journalAttributes' => a('journalAttributes'), 'sortJournalEntries' => a('sortJournalEntries'), 'costAccount' => a('costaccount'), 'revenueAccount' => a('revenueaccount') } query = Query.new(queryAttrs) # Prepare the account list. accountList = PropertyList.new(@project.accounts) accountList.setSorting(a('sortAccounts')) accountList.query = query accountList = filterAccountList(accountList, a('hideAccount'), a('rollupAccount'), a('openNodes')) accountList.sort! # Prepare the resource list. resourceList = PropertyList.new(@project.resources) resourceList.setSorting(a('sortResources')) resourceList.query = query resourceList = filterTaskList(resourceList, nil, a('hideResource'), a('rollupResource'), a('openNodes')) resourceList.sort! # Prepare the task list. taskList = PropertyList.new(@project.tasks) taskList.includeAdopted taskList.setSorting(a('sortTasks')) taskList.query = query taskList = filterTaskList(taskList, nil, a('hideTask'), a('rollupTask'), a('openNodes')) taskList.sort! @fileName = (@report.name[0] == '/' ? '' : @project.outputDir) + @report.name + '.csv' # Generate the table header. headers = [ 'Date' ] + generatePropertyListHeader(accountList, query) + generatePropertyListHeader(resourceList, query) + generatePropertyListHeader(taskList, query) discontinuedColumns = 0 if File.exist?(@fileName) begin @table = CSVFile.new(nil, nil).read(@fileName) rescue error('tr_cannot_read_csv', "Cannot read CSV file #{@fileName}: #{$!}") end if @table[0] != headers # Some columns have changed. We move all discontinued columns to the # last columns and rearrange the others according to the new # headers. New columns will be filled with nil in previous rows. sorter = TableColumnSorter.new(@table) @table = sorter.sort(headers) discontinuedColumns = sorter.discontinuedColumns end else @table = [ headers ] end # Convert empty strings into nil objects and dates in %Y-%m-%d format # into TjTime objects. @table.each do |line| line.length.times do |i| if line[i] == '' line[i] = nil elsif line[i].is_a?(String) && /\d{4}-\d{2}-\d{2}/ =~ line[i] line[i] = TjTime.new(line[i]) end end end query = @project.reportContexts.last.query.dup dateTag = @project['now'].midnight idx = @table.index { |line| line[0] == dateTag } discColumnValues = discontinuedColumns > 0 ? Array.new(discontinuedColumns, nil) : [] if idx # We already have an entry for the current date. All old values of # this line will be overwritten with the current values. The old # values in the discontinued columns will be kept. if discontinuedColumns > 0 discColumnValues = @table[idx][headers.length..-1] end @table[idx] = [] else # Append a new line of values to the table. @table << [] idx = -1 end # The first entry is always the current date. @table[idx] << dateTag # Now add the new values to the line generatePropertyListValues(idx, accountList, query) generatePropertyListValues(idx, resourceList, query) generatePropertyListValues(idx, taskList, query) # Fill the discontinued columns with old values or nil. @table[idx] += discColumnValues # Sort the table by ascending first column dates. We need to ensure that # the header remains the first line in the table. @table.sort! { |l1, l2| l1[0].is_a?(String) ? -1 : (l2[0].is_a?(String) ? 1 : l1[0] <=> l2[0]) } end
to_csv()
click to toggle source
# File lib/taskjuggler/reports/TraceReport.rb, line 174 def to_csv # Convert all TjTime values into String with format %Y-%m-%d and nil # objects into empty Strings. @table.each do |line| line.length.times do |i| if line[i].nil? line[i] = '' elsif line[i].is_a?(TjTime) line[i] = line[i].to_s('%Y-%m-%d') end end end @table end
to_html()
click to toggle source
# File lib/taskjuggler/reports/TraceReport.rb, line 157 def to_html html = [] html << rt_to_html('header') begin plotter = ChartPlotter.new(a('width'), a('height'), @table) plotter.generate html << plotter.to_svg rescue ChartPlotterError => exception warning('chartPlotterError', exception.message, @report.sourceFileInfo) end html << rt_to_html('footer') html end