[Canonical page](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/preview-options/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# PreviewOptions

Options for [`Project.Preview`](<https://docs.dhtmlx.com/planning-engine/net/api/project-preview.md>). They set which part of the project is scheduled, which extra data the [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md>) carries, and which baseline the preview expects. `new PreviewOptions()` schedules the whole project and returns only the changed tasks.

## Declaration

```csharp
public sealed class PreviewOptions : IDeepCloneable<PreviewOptions>
{
    public Subtree? Subtree { get; set; }
    public AnalyticsOptions Analytics { get; set; } = new();
    public bool Reasons { get; set; }
    public string? BaselineId { get; set; }
    public ProfileQuery? Profile { get; set; }

    public PreviewOptions DeepClone();
}
```

Set the properties you need with an object initializer: `new PreviewOptions { Reasons = true }`. `PreviewOptions` doesn't implement `IEquatable<T>`, so two instances compare by reference.

## Properties

| Property | Type | Default | Description |
|---|---|---|---|
| `Subtree` | [`Subtree`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/subtree.md>)`?` | `null` | Schedules only one task's subtree and the tasks that depend on it. `null` schedules the whole project. |
| `Analytics` | [`AnalyticsOptions`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/analytics-options.md>) | `new()` (no analytics) | Requests critical path and slack. Fills [`ScheduleResult.Analytics`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md>). |
| `Reasons` | `bool` | `false` | Fills [`Mutation.Reason`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/mutation.md>) on each update with the [`Reason`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/reason.md>) the task moved. |
| `BaselineId` | `string?` | `null` | The baseline the preview expects. `null` skips the check. |
| `Profile` | [`ProfileQuery`](<https://docs.dhtmlx.com/planning-engine/net/api/core/resources/profile-query.md>)`?` | `null` | Requests a load profile of the previewed dates. Fills [`ScheduleResult.Profile`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md>). |

### Subtree

```csharp
public Subtree? Subtree { get; set; }
```

Limits scheduling to the scope the [`Subtree`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/subtree.md>) value describes. Build the value with `new Subtree(id)`.

### Analytics

```csharp
public AnalyticsOptions Analytics { get; set; } = new();
```

Turns on [`AnalyticsOptions.Slack`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/analytics-options.md>) and [`AnalyticsOptions.CriticalPath`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/analytics-options.md>) for the previewed dates. With both flags `false` (the default), `ScheduleResult.Analytics` is `null`. With either flag set, it holds an [`Analytics`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/analytics.md>) value; check its `Status` before reading the data.

### Reasons

```csharp
public bool Reasons { get; set; }
```

When `true`, each [`Mutation`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/mutation.md>) in `Updates` carries a [`Reason`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/reason.md>) in its `Reason` property. When `false`, `Reason` is always `null`.

### BaselineId

```csharp
public string? BaselineId { get; set; }
```

A baseline token taken from the latest [`ScheduleResult.BaselineId`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md#baselineid>). When it isn't `null` and doesn't name the project's current baseline, [`Project.Preview`](<https://docs.dhtmlx.com/planning-engine/net/api/project-preview.md>) throws a [`ProjectException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/project-exception.md>) with `Code == ProjectError.StaleBaseline`. Use it to stop a preview from running over a baseline that changed underneath the UI.

[`SchedulingChanges.BaselineId`](<https://docs.dhtmlx.com/planning-engine/net/api/core/changes/scheduling-changes.md>) is checked the same way, independently of this property.

### Profile

```csharp
public ProfileQuery? Profile { get; set; }
```

When set, `ScheduleResult.Profile` holds the [`LoadProfile`](<https://docs.dhtmlx.com/planning-engine/net/api/core/resources/load-profile.md>) of the previewed dates over the range and resources the [`ProfileQuery`](<https://docs.dhtmlx.com/planning-engine/net/api/core/resources/profile-query.md>) describes. When `null`, `ScheduleResult.Profile` is `null`. An invalid query makes `Project.Preview` throw an [`InputException`](<https://docs.dhtmlx.com/planning-engine/net/api/core/errors/input-exception.md>).

## Methods

### DeepClone

```csharp
public PreviewOptions DeepClone()
```

Returns a copy that shares no nested object (`Subtree`, `Analytics`, `Profile`) with this one.

## Example

```csharp
using Plen;

var monday = Moment.FromYmdHm(2026, 1, 5, 8, 0) ?? throw new InvalidOperationException("invalid date");
var wednesday = Moment.FromYmdHm(2026, 1, 7, 8, 0) ?? throw new InvalidOperationException("invalid date");
var nextMonday = Moment.FromYmdHm(2026, 1, 12, 8, 0) ?? throw new InvalidOperationException("invalid date");

var data = new ProjectData
{
    Tasks =
    [
        new TaskData("design") { StartDate = monday, Duration = 2.0 },
        new TaskData("build") { StartDate = monday, Duration = 3.0 },
    ],
    Links = [new LinkData { Id = "l1", Source = "design", Target = "build" }],
};

var project = new Project();
var solved = project.Solve(data, new SolveOptions());

// The user drags "design" to Wednesday.
var changes = new SchedulingChanges();
changes.Tasks.Update.Add(new TaskUpdate("design") { StartDate = wednesday });

var preview = project.Preview(changes, new PreviewOptions
{
    Reasons = true,
    BaselineId = solved.BaselineId,
    Profile = new ProfileQuery(monday, nextMonday),
});

foreach (var update in preview.Updates)
    Console.WriteLine($"{update.Id}: {update.StartDate} - {update.EndDate} ({update.Reason})");
```

## Related

- [`Project.Preview`](<https://docs.dhtmlx.com/planning-engine/net/api/project-preview.md>) - the call these options configure
- [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/net/api/core/results/schedule-result.md>) - the returned result
- [`Subtree`](<https://docs.dhtmlx.com/planning-engine/net/api/core/project/subtree.md>) - limiting the preview to one branch
- [Previewing changes](<https://docs.dhtmlx.com/planning-engine/net/live-projects/previewing-changes.md>) - previews, baseline tokens and load
- [Reschedule a branch](<https://docs.dhtmlx.com/planning-engine/net/how-to/reschedule-a-branch.md>) - previewing one subtree
