> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Calculate Progress with Scripts

> Compute task progress automatically in Nextedy GANTT using Item Scripts, based on time estimates, resolved status, or plan completion ratios.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

## Progress Data Model

The Gantt chart stores progress as a float value between `0.0` (no progress) and `1.0` (complete). The progress column in the grid displays this as a percentage (0-100). The default Progress Field widget parameter is `gantt_progress`.

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/umKaPvHwUHw-ZQFM/gantt/diagrams/guides/scripting/progress-calculation-scripts/diagram-1.svg?fit=max&auto=format&n=umKaPvHwUHw-ZQFM&q=85&s=d243d06ce84b0c133ae1234fd8e481a3" alt="diagram" style={{ maxWidth: "740px", width: "100%" }} width="740" height="180" data-path="gantt/diagrams/guides/scripting/progress-calculation-scripts/diagram-1.svg" />
</Frame>

## Calculate Progress from Time Estimates

This script computes progress as `timeSpent / (remainingEstimate + timeSpent)` and automatically sets resolved items to 100%.

In **Widget Parameters > Advanced > Item Script**:

```javascript theme={null}
if(wi.getType().getId() === 'workpackage'){
    var all = (wi.getRemainingEstimate() != null
                   ? wi.getRemainingEstimate().getHours() : 0)
            + (wi.getTimeSpent() != null
                   ? wi.getTimeSpent().getHours() : 0);
    var done = (wi.getTimeSpent() != null
                   ? wi.getTimeSpent().getHours() : 0);

    if(wi.getResolution() != null){
        task.progress = 1;
    } else if(all == 0){
        task.progress = 0;
    } else {
        task.progress = done / all;
    }

    var progressString = (wi.getTimeSpent() != null ? wi.getTimeSpent() : "0h")
        + " | "
        + (wi.getRemainingEstimate() != null ? wi.getRemainingEstimate() : "0h")
        + " (" + Math.round(task.progress * 100) + " %)";
    task.getFields().put("progressString", progressString);
}
```

<Tip title="Adjust the work item type filter">
  The script above filters for `workpackage` items. Change `'workpackage'` to your work item type ID, or remove the `if` statement entirely to apply the calculation to all items.
</Tip>

## Disable Progress Drag

When progress is computed automatically, disable manual progress adjustment. In **Widget Parameters > Advanced > Gantt Config Script**:

```javascript theme={null}
gantt.config.drag_progress = false;
```

This hides the progress drag handle on task bars and prevents users from overriding calculated values.

## Display Progress Text on Task Bars

Show the computed progress summary next to each task bar. In **Gantt Config Script**:

```javascript theme={null}
gantt.config.drag_progress = false;
gantt.templates.rightside_text = function(start, end, task){
    return "<b><img src='" + task.fields.statusIcon + "'/> "
        + task.fields.statusName + "</b> "
        + (task.progress != null ? task.fields.progressString : "");
};
```

This renders the work item status icon, status name, time spent, remaining estimate, and completion percentage to the right of each task bar.

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/XoCXinV6eKUe5dKK/gantt/images/48000983155/3.png?fit=max&auto=format&n=XoCXinV6eKUe5dKK&q=85&s=ae1cfb80f31e0fdc77ccc0f7d91333d9" alt="Gantt Config Script setting rightside_text so the computed progress summary appears to the right of the epic task bar" width="2004" height="854" data-path="gantt/images/48000983155/3.png" />
</Frame>

## Calculate Epic Progress from Children

For epic-level items where time estimates are derived from child stories:

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/XoCXinV6eKUe5dKK/gantt/images/48000983155/1.png?fit=max&auto=format&n=XoCXinV6eKUe5dKK&q=85&s=cbafcf513881a1d7974eccec7dfab102" alt="Epic whose progress is calculated automatically from the progress of its child stories" width="1940" height="666" data-path="gantt/images/48000983155/1.png" />
</Frame>

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/XoCXinV6eKUe5dKK/gantt/images/48000983155/2.png?fit=max&auto=format&n=XoCXinV6eKUe5dKK&q=85&s=e73dd32b214f44233609100c63ab729d" alt="Epic with User Stories as children in the E-library demo, where Initial Estimate, Time Spent and Remaining Estimate are summed from the children" width="1980" height="578" data-path="gantt/images/48000983155/2.png" />
</Frame>

```javascript theme={null}
if(wi.getType().getId() === 'epic'){
    task.type = 'project';
    var all = (wi.getRemainingEstimate() != null
                   ? wi.getRemainingEstimate().getHours() : 0)
            + (wi.getTimeSpent() != null
                   ? wi.getTimeSpent().getHours() : 0);
    var done = (wi.getTimeSpent() != null
                   ? wi.getTimeSpent().getHours() : 0);

    if(wi.getResolution() != null){
        task.progress = 1;
    } else if(all == 0){
        task.progress = 0;
    } else {
        task.progress = done / all;
    }

    var progressString = "Time Spent:"
        + (wi.getTimeSpent() != null ? wi.getTimeSpent() : "0h")
        + " Remaining: "
        + (wi.getRemainingEstimate() != null ? wi.getRemainingEstimate() : "0h")
        + " (" + Math.round(task.progress * 100) + "%)";
    task.getFields().put("progressString", progressString);
}
```

Setting `task.type = 'project'` renders the epic as a summary bar with its schedule derived from children.

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/XoCXinV6eKUe5dKK/gantt/images/48000983155/4.png?fit=max&auto=format&n=XoCXinV6eKUe5dKK&q=85&s=bf43320165de5a7329a1c6e0091a7735" alt="Gantt chart with the epic progress computed automatically from its child stories and shown on the epic summary bar" width="1940" height="666" data-path="gantt/images/48000983155/4.png" />
</Frame>

## Calculate Plan Progress from Resolved Items

For Plans Gantt, compute progress as the ratio of resolved to total work items in a plan. In **Item Script**:

```javascript theme={null}
var allitems = trackerService.queryWorkItems(
    "PLAN:(" + plan.getProjectId() + "/" + plan.getId() + ")", "id").size();
var openitems = trackerService.queryWorkItems(
    "PLAN:(" + plan.getProjectId() + "/" + plan.getId()
    + ") AND HAS_VALUE:resolution", "id").size();
if(allitems > 0){
    task.progress = openitems / allitems;
} else {
    task.progress = 0;
}
task.getFields().put("progressString", openitems + " / " + allitems + " done");
```

<Note title="Plans Gantt context">
  The `plan` variable is only available in the Plans Gantt Item Script. In the Work Items Gantt, use `wi` to access work item data instead.
</Note>

## Verify Your Changes

Save the page and reload the Gantt chart. You should now see:

* Task bars with progress fill matching the computed percentages
* Progress text displayed to the right of each task bar (if configured)
* The progress drag handle hidden (if `drag_progress` is disabled)

## See Also

* [Track and Calculate Progress](/gantt/guides/editing/progress-tracking) for manual progress tracking
* [Configure Right-Side Text on Task Bars](/gantt/guides/visualization/right-side-text) for template customization
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics) for Item Script fundamentals
* [Compute Plan Progress](/gantt/guides/plans/plan-progress) for Plans Gantt progress

<LastReviewed date="2026-07-07" />
