[Canonical page](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/metrics/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Metrics

The measurements of one stage, each paired with its difference from the baseline. [`Project#evaluate`](<https://docs.dhtmlx.com/planning-engine/java/api/project-evaluate.md>) returns them in [`EvaluateResult.baseline`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/evaluate-result.md>), in [`CandidateResult.scheduled`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/candidate-result.md>), and in [`LeveledMetrics.metrics`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/leveled-metrics.md>) for the leveled stage. In the baseline's own `Metrics`, every delta is `0`.

## Declaration

```java
package org.dhtmlx.plen;

public class Metrics extends ValueRecord implements DeepCloneable<Metrics>
```

Treat a returned `Metrics` as read-only. Call `deepClone()` before changing it.

## Constructors

### Metrics()

```java
public Metrics()
```

Creates an empty value: `finish` and `overload` are `null`, `conflicts` and `cycles` are `new Amount(0, 0)`, `cost` is `0.0`. `evaluate` always fills every field.

## Fields

| Field | Type | Default | Description |
|---|---|---|---|
| `finish` | [`Finish`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/metrics.md#finish>) | `null` | Project finish and the finish of each focus task. Never `null` in a returned value. |
| `overload` | [`Overload`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/overload.md>) | `null` | Resource overload of the stage, in total, per resource and per focus task. Never `null` in a returned value. |
| `conflicts` | [`Amount`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/overload.md#amount>) | `new Amount(0, 0)` | Number of entries in the stage's `conflicts` list. |
| `cycles` | [`Amount`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/overload.md#amount>) | `new Amount(0, 0)` | Number of entries in the stage's `cycles` list. Greater than `0` when the candidate made the plan cyclic. |
| `cost` | `double` | `0.0` | Score of the stage. Lower is better. |

`cost` is computed from the other fields by one fixed formula:

```
cost = max(0, finish.project.delta)
     + overload.total.value
     + 1000 × (conflicts.value + cycles.value)
```

The `finish.project` term counts as `0` when `finish.project` is `null`. The `1000 ×` penalty ranks every stage with conflicts or cycles after every stage without them. To rank by another rule, compare the raw fields instead of `cost`.

## Methods

### withFinish, withOverload, withConflicts, withCycles, withCost

```java
public Metrics withFinish(Finish value)
public Metrics withOverload(Overload value)
public Metrics withConflicts(Amount value)
public Metrics withCycles(Amount value)
public Metrics withCost(double value)
```

Each setter assigns its field and returns this instance. `withCost` stores the value as given. It doesn't recompute it from the other fields.

**Returns**: this `Metrics`.

### deepClone

```java
public Metrics deepClone()
```

Returns a deep copy. `finish`, `overload`, the two `Amount` values and every list inside them are copied.

**Returns**: a new `Metrics`.

**Errors**: `NullPointerException` when `finish` or `overload` is `null`.

### copy

```java
public Metrics copy()
```

Returns a shallow copy that shares `finish` and `overload` with the original. `conflicts` and `cycles` get their own `Amount` instances.

**Returns**: a new `Metrics`.

### equals, hashCode, toString

```java
public boolean equals(Object other)
public int hashCode()
public String toString()
```

Inherited from [`ValueRecord`](<https://docs.dhtmlx.com/planning-engine/java/api/support/value-record.md>). Two values are equal when every field is equal: nested objects and lists compare element by element. `toString()` prints every field, for logging.

## Finish

Finish dates of the stage: the project and each task listed in [`EvaluateOptions.focus`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/evaluate-options.md#focus>).

```java
public class Finish extends ValueRecord implements DeepCloneable<Finish>
```

| Field | Type | Default | Description |
|---|---|---|---|
| `project` | [`Shift`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/metrics.md#shift>) | `null` | Latest end over the stage's scheduled tasks. `null` when the project has no tasks. Its `delta` is measured on the global calendar and is `0` when the baseline has no tasks. |
| `tasks` | `Vec<`[`TaskFinish`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/metrics.md#taskfinish>)`>` | empty | One entry per focus task, in `focus` order. Empty when `focus` is empty. |

Setters: `withProject(Shift)`, `withTasks(Vec<TaskFinish>)` and `withTasks(Collection<? extends TaskFinish>)`. `deepClone()` throws `NullPointerException` when `tasks` is `null`.

## TaskFinish

The finish of one focus task.

```java
public class TaskFinish extends ValueRecord implements DeepCloneable<TaskFinish>
```

| Field | Type | Default | Description |
|---|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/java/api/data/id.md>) | `null` | The focus task. |
| `finish` | [`Shift`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/metrics.md#shift>) | `null` | The task's finish. `null` when the candidate removed the task. Its `delta` is measured on the task's calendar. |

Setters: `withId(Id)`, `withFinish(Shift)`.

## Shift

A finish date and how far it moved from the baseline finish.

```java
public class Shift extends ValueRecord implements DeepCloneable<Shift>
```

| Field | Type | Default | Description |
|---|---|---|---|
| `date` | [`Moment`](<https://docs.dhtmlx.com/planning-engine/java/api/data/moment.md>) | `new Moment(0)` | The finish date in this stage. |
| `delta` | `double` | `0.0` | Working time from the baseline finish to `date`, in [`SchedulingConfig.durationUnit`](<https://docs.dhtmlx.com/planning-engine/java/api/data/scheduling-config.md#durationunit>). Positive when the stage finishes later. |

Setters: `withDate(Moment)`, `withDelta(double)`.

`Finish`, `TaskFinish` and `Shift` have the same `deepClone`, `copy`, `equals`, `hashCode` and `toString` members as `Metrics`.

## Example

Score a two-day extension of task `1` and read how far the project finish moves.

```java
import java.util.List;
import org.dhtmlx.plen.*;

public class MetricsExample {
  public static void main(String[] args) throws Exception {
    Moment monday = Moment.fromYmdHm(2026, 8, 10, 8, 0);
    ProjectData data = new ProjectData()
        .withTasks(List.of(
            new TaskData(Id.num(1)).withStartDate(monday).withDuration(3.0)));

    Project project = new Project();
    project.solve(data, new SolveOptions());

    SchedulingChanges changes = new SchedulingChanges();
    changes.tasks.update.add(new TaskUpdate()
        .withId(Id.num(1))
        .withDuration(Patch.of(5.0)));

    EvaluateResult result = project.evaluate(
        List.of(new Candidate().withId(Id.str("longer")).withChanges(changes)),
        new EvaluateOptions().withFocus(List.of(Id.num(1))));

    Metrics metrics = result.candidates.get(0).scheduled;
    if (metrics != null && metrics.finish.project != null) {
      Shift finish = metrics.finish.project;
      System.out.println("finish " + finish.date + ", delta " + finish.delta
          + ", cost " + metrics.cost);
    }
  }
}
```

## Related

- [`Overload`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/overload.md>) - the type of `overload`
- [`CandidateResult`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/candidate-result.md>) - holds the metrics of each candidate stage
- [`EvaluateOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/evaluate/evaluate-options.md>) - sets the focus tasks and the leveled stage
- [Evaluating alternatives](<https://docs.dhtmlx.com/planning-engine/java/resources-and-assignment/evaluating-alternatives.md#metrics-and-cost>) - comparing candidates by metrics and cost
- [Suggesting assignments](<https://docs.dhtmlx.com/planning-engine/java/resources-and-assignment/suggesting-assignments.md#reading-the-proposal>) - the metrics of a staffing proposal
