Skip to main content

Slack

PRO

The functionality is available in PRO Edition only

Slack (float) shows how much a task can be delayed without affecting successors or the overall project end date. When enabled, slack is calculated automatically.

Enabling slack calculation

To enable slack, use the slack property:

<script setup>
import { Gantt } from "@svar-ui/vue-gantt";
import { getData } from "./data";

const { tasks, links, scales } = getData();
</script>

<template>
<Gantt :tasks="tasks" :links="links" :scales="scales" slack />
</template>

Once enabled, the Gantt calculates slack for each task and attaches an object to it:

slack?: {
earliestStart: Date; // Earliest date the task can start (forward pass result)
latestStart: Date; // Latest date the task can start without delaying the project
totalSlack: number; // Days the task can be delayed without affecting the project end (0 = critical)
freeSlack: number; // Days the task can be delayed without affecting any successor
}

Note: Slack values are calculated in working days when a calendar is applied.

Displaying slack in grid columns

You can add custom columns to the grid to visualize slack values. Use the built-in slack column ID to access the slack object directly via the template function, or use getter of the columns property to extract a specific field:

<script setup>
import { Gantt } from "@svar-ui/vue-gantt";
import { getData } from "./data";

const { tasks, links, scales } = getData();

const columns = [
{ id: "text", header: "Task name", flexgrow: 1 },
{
id: "earliestStart",
header: "Earliest start",
align: "center",
width: 120,
getter: t => t.slack.earliestStart,
template: v => (v ? v.toLocaleDateString() : "-"),
},
{
id: "latestStart",
header: "Latest start",
align: "center",
width: 120,
getter: t => t.slack.latestStart,
template: v => (v ? v.toLocaleDateString() : "-"),
},
{
id: "freeSlack",
header: "Free slack",
align: "center",
width: 100,
getter: t => t.slack.freeSlack,
template: v => v ?? "-",
},
{
id: "totalSlack",
header: "Total slack",
align: "center",
width: 100,
getter: t => t.slack.totalSlack,
},
];
</script>

<template>
<Gantt :tasks="tasks" :links="links" :scales="scales" :columns="columns" slack />
</template>
note

If a column displays a derived or nested value (for example, task.slack.totalSlack), use getter to extract the value. The returned value is used for sorting and is passed to the template function as its first argument.

Total slack is also visualized directly on task bars for normal scheduled tasks (not milestones or summary tasks).

Slack with unscheduled tasks

When unscheduledTasks is enabled, slack values are not applicable to unscheduled tasks. You can handle this via the column template:

<script setup>
import { Gantt } from "@svar-ui/vue-gantt";
import { getData } from "./data";

const { tasks, links, scales } = getData();

const columns = [
{
id: "freeSlack",
header: "Free slack",
align: "center",
width: 100,
getter: t => t.slack?.freeSlack,
template: v => v ?? "-"
},
{
id: "totalSlack",
header: "Total slack",
align: "center",
width: 100,
getter: t => t.slack?.totalSlack,
template: v => v ?? "-"
}
];
</script>

<template>
<Gantt :tasks="tasks" :links="links" :scales="scales" :columns="columns" slack unscheduledTasks />
</template>

Accessing slack data

Once slack is calculated, you can get the corresponding data via the API (api.getState(), api.getTask(), api.serialize()).

// Access slack for a specific task
const freeSlack = api.getTask(id).slack.freeSlack;

// Iterate over all tasks
api.getState().tasks.forEach(task => {
console.log(task.slack?.totalSlack);
});

// Or via serialized data
api.serialize().forEach(task => {
console.log(task.slack?.freeSlack);
});

Related sample: Slack

Related articles: