The chronological worklog chart shows time logged on issues based on the issue attribute.


Chart preview

Parameters

Parameter


Type

Default value
UICode
JQLjqlJQL Autocomplete
Chart typeChartTypeChart Type PickerBar
Time periodTimeperiodTime PeriodMonth
Group byGroupbyGroup By PickerIssue type
Layout Script

Used layout: Timeseries All.

function formatTooltipAsHours(value, ratio, id, index)
{
    return value.toFixed(2) + ' h';
}
 
function formatQuarter(d)
{
    if (d instanceof Date)
    {
        var q = d.getMonth();
        q = parseInt(q / 3) + 1;
        return 'Q' + q;
    }
    return '';
}
 
function formatHalfyear(d)
{
    if (d instanceof Date)
    {
        var q = d.getMonth();
        q = parseInt(q / 6) + 1;
        return 'H' + q;
    }
    return '';
}
 
var c3arg = {
    onrendered: updateFrameHeight,
    data: chartData,
    grid: {
        y: {
            show: true
        },
        x: {
            show: true
        }
    },
    axis: {
        x: {
            type: 'timeseries',
            label: {
                text: chartData.custom.xLabel,
                position: 'outer-left'
            },
            tick: {
                format: eval(chartData.custom.xTickFormat),
                culling: {
                    max: 25
                },
                fit: true,
                multiline: false
            }
        },
        y: {
            label: chartData.ytype
        }
    }
};
 
if (chartData.custom && chartData.custom.tooltip)
{
    var tooltipFunction = eval(chartData.custom.tooltip);
    c3arg.tooltip = {
        format: {
            value: tooltipFunction
        }
    };
}
 
if ( chartData.custom && chartData.custom.gauge_max)
{
    c3arg.gauge = {
        max: parseFloat(chartData.custom.gauge_max)
    };
}
 
c3.generate(c3arg);
Data Script
import java.lang.reflect.Field;
import java.math.BigDecimal;
 
import org.apache.lucene.document.Document;
 
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.DocumentIssueImpl;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.worklog.Worklog;
import com.atlassian.jira.issue.worklog.WorklogManager;
import com.atlassian.jira.jql.parser.JqlParseException;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.query.Query;
import com.atlassian.jira.util.I18nHelper;
 
import com.decadis.jira.xchart.api.ChartParam;
import com.decadis.jira.xchart.api.model.Period
import com.decadis.jira.xchart.api.util.DateUtils;
 
def i18n = ComponentAccessor.getJiraAuthenticationContext().getI18nHelper();
def wlm = ComponentAccessor.getWorklogManager();
def metaCountGroup = chartBuilder.newDataCollector();
 
JqlQueryParser jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class);
Query query = null;
 
Period selectedPeriod = Period.fromString(TimePeriod);
try
{
  query = jqlQueryParser.parseQuery(JQL);
} catch (JqlParseException e)
{
  throw new IllegalArgumentException("Bad JQL: " + jql);
}
 
def groupValueExtractor = chartBuilder.getGrouper(GroupBy);
Field documentField;
try
{
  documentField = DocumentIssueImpl.class.getDeclaredField("document");
  documentField.setAccessible(true);
  for ( Issue issue : chartBuilder.getFilterUtils().performSearch(query, user) )
  {
    Document doc = (Document) documentField.get(issue);
    for ( Worklog wl : wlm.getByIssue(issue) )
    {
      String x = dateUtils.getPeriodGroup(wl.getCreated(), selectedPeriod);
      BigDecimal value = BigDecimal.valueOf(wl.getTimeSpent()).divide(BigDecimal.valueOf(3600), 4, BigDecimal.ROUND_HALF_UP);
      for ( String group : groupValueExtractor.getGroups(doc) )
      {
        metaCountGroup.addValue(value, group, x);
      }
    }
  }
} catch (Exception e){}
 
metaCountGroup.fillMissingValues();
def chartData = chartBuilder.newChartData(i18n.getText("common.concepts.time.spent"));
for ( String grpKey : metaCountGroup.keySet() )
{
  chartData.addGroupName(grpKey, groupValueExtractor.getResolvedValue(grpKey, null));
}
 
chartData.setxFormat("%Y.%m.%d");
chartData.setPeriod(selectedPeriod);
chartData.setType(ChartType);
chartData.addCustomData("tooltip", "formatTooltipAsHours");
 
chartBuilder.getChartUtil().transformResult(metaCountGroup, chartData, true);
 
return chartData;

If you still have questions, feel free to refer to our support team.