Several numbers on every line, side by side (columns, measures): headcount and full-time equivalents of the same teams, summed by the same derivation. Reach for it where one sheet has to answer in more than one unit.
import { Calculation, Given, Sum, Chain, Plus, Minus, Interim } from "@umriss-ui/calculation";
metrics on the calculation names each metric once, with its unit and places; every value is then an object with a number for each metric id. Each metric is worked on its own - nothing ever takes numbers from two of them (ADR-0038).
The head names each metric above its column. The unit stands again only where a result closes: the Result, an interim, the line that closes an open derivation.
A number one metric does not have is null, and makes absent only what depends on it in that metric; the badge says which metric, the sentence the full reason.
Where the figures leave the labels less room than they need, and less than 10 rem, each line puts them on a line beneath its label, still in their columns. The component measures this: it depends on the labels, the number of metrics and their digits, not on a breakpoint.
metrics puts several numbers on every line, each in its own column; every value is then an object with a number per metric.
import { Calculation, Given, Sum } from "@umriss-ui/calculation";
import type { Metric } from "@umriss-ui/calculation";
/* Data from the planning world, written out here so the example runs on its own. */
interface Person {
id: string;
name: string;
role: "Developer" | "Designer" | "Product manager" | "QA engineer";
team: "Web" | "Apps";
/** Hours a week they can be planned for. */
capacity: number;
}
const PEOPLE: readonly Person[] = [
{ id: "maya", name: "Maya Lindgren", role: "Product manager", team: "Web", capacity: 32 },
{ id: "arjun", name: "Arjun Mehta", role: "Developer", team: "Web", capacity: 40 },
{ id: "chloe", name: "Chloe Durand", role: "Developer", team: "Web", capacity: 40 },
{ id: "noah", name: "Noah Fischer", role: "Designer", team: "Web", capacity: 24 },
{ id: "eva", name: "Eva Novak", role: "QA engineer", team: "Web", capacity: 40 },
{ id: "luis", name: "Luis Moreno", role: "Product manager", team: "Apps", capacity: 40 },
{ id: "hana", name: "Hana Sato", role: "Developer", team: "Apps", capacity: 40 },
{ id: "kofi", name: "Kofi Mensah", role: "Developer", team: "Apps", capacity: 32 },
{ id: "freya", name: "Freya Olsen", role: "Designer", team: "Apps", capacity: 40 },
{ id: "david", name: "David Kowalski", role: "QA engineer", team: "Apps", capacity: 20 },
];
const METRICS: Metric[] = [
{ id: "heads", label: "Headcount", unit: "HC" },
{ id: "fte", label: "Full-time equivalents", unit: "FTE", decimals: 1 },
];
/* A full-time week is 40 hours. */
const staffOf = (team: "Web" | "Apps") => {
const people = PEOPLE.filter((person) => person.team === team);
return { heads: people.length, fte: people.reduce((sum, person) => sum + person.capacity, 0) / 40 };
};
export default function TwoTeams() {
return (
<Calculation aria-label="Staff of Tidewell" metrics={METRICS}>
<Sum label="Tidewell">
<Given label="Web team" value={staffOf("Web")} />
<Given label="Apps team" value={staffOf("Apps")} />
</Sum>
</Calculation>
);
}
null for one metric makes absent only what depends on it in that metric, with the reason; the other metric sums on.
import { Calculation, Given, Sum } from "@umriss-ui/calculation";
import type { Metric } from "@umriss-ui/calculation";
const METRICS: Metric[] = [
{ id: "heads", label: "Headcount", unit: "HC" },
{ id: "fte", label: "Full-time equivalents", unit: "FTE", decimals: 1 },
];
export default function NotRecorded() {
return (
<Calculation aria-label="Staff of customer service" metrics={METRICS}>
<Sum label="Customer service">
<Given label="Service desk" value={{ heads: 7, fte: 5.9 }} />
<Given label="Returns" value={{ heads: 3, fte: 2.5 }} />
<Given
label="Working students"
value={{ heads: 4, fte: null }}
explanation="Paid by the hour; no contracted hours to count."
/>
</Sum>
</Calculation>
);
}
A tree of sums, built from data: every cost centre folds to its total and opens into its teams, each metric summed on its own.
import { Calculation, Given, Sum } from "@umriss-ui/calculation";
import type { Metric } from "@umriss-ui/calculation";
/* Data from the controlling world, written out here so the example runs on its own. */
interface CostCentre {
id: string;
name: string;
owner: string;
/** The budget of one month. */
monthlyBudget: number;
}
const COST_CENTRES: readonly CostCentre[] = [
{ id: "CC-1100", name: "Sales", owner: "Helen Marsh", monthlyBudget: 142_000 },
{ id: "CC-1200", name: "Marketing", owner: "Rafael Ortiz", monthlyBudget: 68_000 },
{ id: "CC-2100", name: "Engineering", owner: "Anika Sørensen", monthlyBudget: 188_000 },
{ id: "CC-2200", name: "Design", owner: "Paul Whitaker", monthlyBudget: 54_000 },
{ id: "CC-3100", name: "Customer service", owner: "Grace Obi", monthlyBudget: 61_000 },
{ id: "CC-4100", name: "Finance", owner: "Martina Vogel", monthlyBudget: 47_000 },
{ id: "CC-4200", name: "People", owner: "Daniel Frost", monthlyBudget: 39_000 },
{ id: "CC-4300", name: "IT", owner: "Kenji Arai", monthlyBudget: 83_000 },
{ id: "CC-4400", name: "Facilities", owner: "Olga Ivanova", monthlyBudget: 72_000 },
];
interface Team {
/** The cost centre the team books to. */
costCentre: string;
name: string;
/** People employed, whatever their hours. */
headcount: number;
/** Full-time equivalents: contracted hours over 40 a week. */
fte: number;
/** Staff cost of a month, in thousand euros. */
monthlyCost: number;
}
/** Every team, on 17 March: 102 people, 91.5 full-time equivalents. */
const TEAMS: readonly Team[] = [
{ costCentre: "CC-1100", name: "Field sales North", headcount: 9, fte: 8.6, monthlyCost: 61.2 },
{ costCentre: "CC-1100", name: "Field sales South", headcount: 8, fte: 7.5, monthlyCost: 53.9 },
{ costCentre: "CC-1100", name: "Inside sales", headcount: 6, fte: 5.2, monthlyCost: 29.8 },
{ costCentre: "CC-1100", name: "Key accounts", headcount: 4, fte: 4.0, monthlyCost: 33.6 },
{ costCentre: "CC-1200", name: "Brand", headcount: 3, fte: 2.8, monthlyCost: 19.4 },
{ costCentre: "CC-1200", name: "Online marketing", headcount: 4, fte: 3.5, monthlyCost: 24.1 },
{ costCentre: "CC-1200", name: "Trade fairs", headcount: 2, fte: 1.5, monthlyCost: 10.2 },
{ costCentre: "CC-3100", name: "Service desk", headcount: 7, fte: 5.9, monthlyCost: 31.3 },
{ costCentre: "CC-3100", name: "Returns", headcount: 3, fte: 2.5, monthlyCost: 12.6 },
{ costCentre: "CC-2100", name: "Seating", headcount: 6, fte: 5.8, monthlyCost: 43.5 },
{ costCentre: "CC-2100", name: "Desks", headcount: 7, fte: 6.5, monthlyCost: 48.1 },
{ costCentre: "CC-2100", name: "Storage", headcount: 5, fte: 4.6, monthlyCost: 33.9 },
{ costCentre: "CC-2100", name: "Test lab", headcount: 3, fte: 2.5, monthlyCost: 16.8 },
{ costCentre: "CC-2200", name: "Industrial design", headcount: 4, fte: 3.6, monthlyCost: 27.2 },
{ costCentre: "CC-2200", name: "Colour and material", headcount: 2, fte: 1.8, monthlyCost: 12.9 },
{ costCentre: "CC-4100", name: "Accounting", headcount: 5, fte: 4.4, monthlyCost: 27.5 },
{ costCentre: "CC-4100", name: "Controlling", headcount: 3, fte: 3.0, monthlyCost: 21.3 },
{ costCentre: "CC-4200", name: "Recruiting", headcount: 2, fte: 1.8, monthlyCost: 12.4 },
{ costCentre: "CC-4200", name: "Payroll", headcount: 2, fte: 1.5, monthlyCost: 9.6 },
{ costCentre: "CC-4300", name: "Workplace", headcount: 4, fte: 3.8, monthlyCost: 24.2 },
{ costCentre: "CC-4300", name: "Applications", headcount: 5, fte: 4.5, monthlyCost: 34.8 },
{ costCentre: "CC-4400", name: "Buildings", headcount: 3, fte: 3.0, monthlyCost: 16.9 },
{ costCentre: "CC-4400", name: "Canteen", headcount: 5, fte: 3.2, monthlyCost: 14.7 },
];
const METRICS: Metric[] = [
{ id: "heads", label: "Headcount", unit: "HC" },
{ id: "fte", label: "Full-time equivalents", unit: "FTE", decimals: 1 },
];
const COMMERCIAL = ["CC-1100", "CC-1200", "CC-3100"];
export default function BusinessLine() {
return (
<Calculation aria-label="Staff of the commercial business line, 17 March" metrics={METRICS}>
<Sum label="Commercial">
{COMMERCIAL.map((id) => (
<Sum key={id} label={COST_CENTRES.find((centre) => centre.id === id)!.name}>
{TEAMS.filter((team) => team.costCentre === id).map((team) => (
<Given key={team.name} label={team.name} value={{ heads: team.headcount, fte: team.fte }} />
))}
</Sum>
))}
</Sum>
</Calculation>
);
}
The chain works per metric too: joiners added, leavers taken away, and every interim closes with its units.
import { Calculation, Chain, Given, Interim, Minus, Plus } from "@umriss-ui/calculation";
import type { Metric } from "@umriss-ui/calculation";
const METRICS: Metric[] = [
{ id: "heads", label: "Headcount", unit: "HC" },
{ id: "fte", label: "Full-time equivalents", unit: "FTE", decimals: 1 },
];
export default function StaffMovement() {
return (
<Calculation aria-label="Staff movement of Carrow & Lisle since 1 January" metrics={METRICS}>
<Chain>
<Given label="Staff on 1 January" value={{ heads: 100, fte: 89.9 }} source="Payroll" />
<Plus label="Joiners" value={{ heads: 5, fte: 4.6 }} />
<Minus label="Leavers" value={{ heads: 2, fte: 1.8 }} />
<Interim label="Under contract" />
<Minus label="Gone on parental leave" value={{ heads: 2, fte: 1.6 }} />
<Plus label="Back from parental leave" value={{ heads: 1, fte: 0.4 }} explanation="Back part-time, 16 hours a week." />
<Interim label="Staff on 17 March" />
</Chain>
</Calculation>
);
}
Any number of metrics, each with its unit and places. Narrow, where the figures leave the label too little room, each line puts them beneath its label.
import { Calculation, Given, Sum } from "@umriss-ui/calculation";
import type { Metric } from "@umriss-ui/calculation";
/* Data from the controlling world, written out here so the example runs on its own. */
interface CostCentre {
id: string;
name: string;
owner: string;
/** The budget of one month. */
monthlyBudget: number;
}
const COST_CENTRES: readonly CostCentre[] = [
{ id: "CC-1100", name: "Sales", owner: "Helen Marsh", monthlyBudget: 142_000 },
{ id: "CC-1200", name: "Marketing", owner: "Rafael Ortiz", monthlyBudget: 68_000 },
{ id: "CC-2100", name: "Engineering", owner: "Anika Sørensen", monthlyBudget: 188_000 },
{ id: "CC-2200", name: "Design", owner: "Paul Whitaker", monthlyBudget: 54_000 },
{ id: "CC-3100", name: "Customer service", owner: "Grace Obi", monthlyBudget: 61_000 },
{ id: "CC-4100", name: "Finance", owner: "Martina Vogel", monthlyBudget: 47_000 },
{ id: "CC-4200", name: "People", owner: "Daniel Frost", monthlyBudget: 39_000 },
{ id: "CC-4300", name: "IT", owner: "Kenji Arai", monthlyBudget: 83_000 },
{ id: "CC-4400", name: "Facilities", owner: "Olga Ivanova", monthlyBudget: 72_000 },
];
interface Team {
/** The cost centre the team books to. */
costCentre: string;
name: string;
/** People employed, whatever their hours. */
headcount: number;
/** Full-time equivalents: contracted hours over 40 a week. */
fte: number;
/** Staff cost of a month, in thousand euros. */
monthlyCost: number;
}
/** Every team, on 17 March: 102 people, 91.5 full-time equivalents. */
const TEAMS: readonly Team[] = [
{ costCentre: "CC-1100", name: "Field sales North", headcount: 9, fte: 8.6, monthlyCost: 61.2 },
{ costCentre: "CC-1100", name: "Field sales South", headcount: 8, fte: 7.5, monthlyCost: 53.9 },
{ costCentre: "CC-1100", name: "Inside sales", headcount: 6, fte: 5.2, monthlyCost: 29.8 },
{ costCentre: "CC-1100", name: "Key accounts", headcount: 4, fte: 4.0, monthlyCost: 33.6 },
{ costCentre: "CC-1200", name: "Brand", headcount: 3, fte: 2.8, monthlyCost: 19.4 },
{ costCentre: "CC-1200", name: "Online marketing", headcount: 4, fte: 3.5, monthlyCost: 24.1 },
{ costCentre: "CC-1200", name: "Trade fairs", headcount: 2, fte: 1.5, monthlyCost: 10.2 },
{ costCentre: "CC-3100", name: "Service desk", headcount: 7, fte: 5.9, monthlyCost: 31.3 },
{ costCentre: "CC-3100", name: "Returns", headcount: 3, fte: 2.5, monthlyCost: 12.6 },
{ costCentre: "CC-2100", name: "Seating", headcount: 6, fte: 5.8, monthlyCost: 43.5 },
{ costCentre: "CC-2100", name: "Desks", headcount: 7, fte: 6.5, monthlyCost: 48.1 },
{ costCentre: "CC-2100", name: "Storage", headcount: 5, fte: 4.6, monthlyCost: 33.9 },
{ costCentre: "CC-2100", name: "Test lab", headcount: 3, fte: 2.5, monthlyCost: 16.8 },
{ costCentre: "CC-2200", name: "Industrial design", headcount: 4, fte: 3.6, monthlyCost: 27.2 },
{ costCentre: "CC-2200", name: "Colour and material", headcount: 2, fte: 1.8, monthlyCost: 12.9 },
{ costCentre: "CC-4100", name: "Accounting", headcount: 5, fte: 4.4, monthlyCost: 27.5 },
{ costCentre: "CC-4100", name: "Controlling", headcount: 3, fte: 3.0, monthlyCost: 21.3 },
{ costCentre: "CC-4200", name: "Recruiting", headcount: 2, fte: 1.8, monthlyCost: 12.4 },
{ costCentre: "CC-4200", name: "Payroll", headcount: 2, fte: 1.5, monthlyCost: 9.6 },
{ costCentre: "CC-4300", name: "Workplace", headcount: 4, fte: 3.8, monthlyCost: 24.2 },
{ costCentre: "CC-4300", name: "Applications", headcount: 5, fte: 4.5, monthlyCost: 34.8 },
{ costCentre: "CC-4400", name: "Buildings", headcount: 3, fte: 3.0, monthlyCost: 16.9 },
{ costCentre: "CC-4400", name: "Canteen", headcount: 5, fte: 3.2, monthlyCost: 14.7 },
];
const METRICS: Metric[] = [
{ id: "heads", label: "Headcount", unit: "HC" },
{ id: "fte", label: "Full-time equivalents", unit: "FTE", decimals: 1 },
{ id: "cost", label: "Staff cost a month", unit: "k€", decimals: 1 },
];
const PRODUCT = ["CC-2100", "CC-2200"];
export default function StaffCost() {
return (
<Calculation aria-label="Staff and staff cost of the product business line" metrics={METRICS}>
<Sum label="Product">
{PRODUCT.map((id) => (
<Sum key={id} label={COST_CENTRES.find((centre) => centre.id === id)!.name}>
{TEAMS.filter((team) => team.costCentre === id).map((team) => (
<Given
key={team.name}
label={team.name}
value={{ heads: team.headcount, fte: team.fte, cost: team.monthlyCost }}
/>
))}
</Sum>
))}
</Sum>
</Calculation>
);
}
Three levels from data - business line, cost centre, team - and three metrics: 23 teams folded to three lines a reader opens one by one.
import { Calculation, Given, Sum } from "@umriss-ui/calculation";
import type { Metric } from "@umriss-ui/calculation";
/* Data from the controlling world, written out here so the example runs on its own. */
interface CostCentre {
id: string;
name: string;
owner: string;
/** The budget of one month. */
monthlyBudget: number;
}
const COST_CENTRES: readonly CostCentre[] = [
{ id: "CC-1100", name: "Sales", owner: "Helen Marsh", monthlyBudget: 142_000 },
{ id: "CC-1200", name: "Marketing", owner: "Rafael Ortiz", monthlyBudget: 68_000 },
{ id: "CC-2100", name: "Engineering", owner: "Anika Sørensen", monthlyBudget: 188_000 },
{ id: "CC-2200", name: "Design", owner: "Paul Whitaker", monthlyBudget: 54_000 },
{ id: "CC-3100", name: "Customer service", owner: "Grace Obi", monthlyBudget: 61_000 },
{ id: "CC-4100", name: "Finance", owner: "Martina Vogel", monthlyBudget: 47_000 },
{ id: "CC-4200", name: "People", owner: "Daniel Frost", monthlyBudget: 39_000 },
{ id: "CC-4300", name: "IT", owner: "Kenji Arai", monthlyBudget: 83_000 },
{ id: "CC-4400", name: "Facilities", owner: "Olga Ivanova", monthlyBudget: 72_000 },
];
interface Team {
/** The cost centre the team books to. */
costCentre: string;
name: string;
/** People employed, whatever their hours. */
headcount: number;
/** Full-time equivalents: contracted hours over 40 a week. */
fte: number;
/** Staff cost of a month, in thousand euros. */
monthlyCost: number;
}
/** Every team, on 17 March: 102 people, 91.5 full-time equivalents. */
const TEAMS: readonly Team[] = [
{ costCentre: "CC-1100", name: "Field sales North", headcount: 9, fte: 8.6, monthlyCost: 61.2 },
{ costCentre: "CC-1100", name: "Field sales South", headcount: 8, fte: 7.5, monthlyCost: 53.9 },
{ costCentre: "CC-1100", name: "Inside sales", headcount: 6, fte: 5.2, monthlyCost: 29.8 },
{ costCentre: "CC-1100", name: "Key accounts", headcount: 4, fte: 4.0, monthlyCost: 33.6 },
{ costCentre: "CC-1200", name: "Brand", headcount: 3, fte: 2.8, monthlyCost: 19.4 },
{ costCentre: "CC-1200", name: "Online marketing", headcount: 4, fte: 3.5, monthlyCost: 24.1 },
{ costCentre: "CC-1200", name: "Trade fairs", headcount: 2, fte: 1.5, monthlyCost: 10.2 },
{ costCentre: "CC-3100", name: "Service desk", headcount: 7, fte: 5.9, monthlyCost: 31.3 },
{ costCentre: "CC-3100", name: "Returns", headcount: 3, fte: 2.5, monthlyCost: 12.6 },
{ costCentre: "CC-2100", name: "Seating", headcount: 6, fte: 5.8, monthlyCost: 43.5 },
{ costCentre: "CC-2100", name: "Desks", headcount: 7, fte: 6.5, monthlyCost: 48.1 },
{ costCentre: "CC-2100", name: "Storage", headcount: 5, fte: 4.6, monthlyCost: 33.9 },
{ costCentre: "CC-2100", name: "Test lab", headcount: 3, fte: 2.5, monthlyCost: 16.8 },
{ costCentre: "CC-2200", name: "Industrial design", headcount: 4, fte: 3.6, monthlyCost: 27.2 },
{ costCentre: "CC-2200", name: "Colour and material", headcount: 2, fte: 1.8, monthlyCost: 12.9 },
{ costCentre: "CC-4100", name: "Accounting", headcount: 5, fte: 4.4, monthlyCost: 27.5 },
{ costCentre: "CC-4100", name: "Controlling", headcount: 3, fte: 3.0, monthlyCost: 21.3 },
{ costCentre: "CC-4200", name: "Recruiting", headcount: 2, fte: 1.8, monthlyCost: 12.4 },
{ costCentre: "CC-4200", name: "Payroll", headcount: 2, fte: 1.5, monthlyCost: 9.6 },
{ costCentre: "CC-4300", name: "Workplace", headcount: 4, fte: 3.8, monthlyCost: 24.2 },
{ costCentre: "CC-4300", name: "Applications", headcount: 5, fte: 4.5, monthlyCost: 34.8 },
{ costCentre: "CC-4400", name: "Buildings", headcount: 3, fte: 3.0, monthlyCost: 16.9 },
{ costCentre: "CC-4400", name: "Canteen", headcount: 5, fte: 3.2, monthlyCost: 14.7 },
];
interface BusinessLine {
name: string;
/** Its cost centres, in the order a report lists them. */
costCentres: readonly string[];
}
/** How the company reports: three business lines over the nine cost centres. */
const BUSINESS_LINES: readonly BusinessLine[] = [
{ name: "Commercial", costCentres: ["CC-1100", "CC-1200", "CC-3100"] },
{ name: "Product", costCentres: ["CC-2100", "CC-2200"] },
{ name: "Corporate services", costCentres: ["CC-4100", "CC-4200", "CC-4300", "CC-4400"] },
];
const METRICS: Metric[] = [
{ id: "heads", label: "Headcount", unit: "HC" },
{ id: "fte", label: "Full-time equivalents", unit: "FTE", decimals: 1 },
{ id: "cost", label: "Staff cost a month", unit: "k€", decimals: 1 },
];
const centreName = (id: string) => COST_CENTRES.find((centre) => centre.id === id)!.name;
export default function WholeCompany() {
return (
<Calculation aria-label="Staff of Carrow & Lisle, 17 March" metrics={METRICS}>
<Sum label="Carrow & Lisle">
{BUSINESS_LINES.map((line) => (
<Sum key={line.name} label={line.name}>
{line.costCentres.map((id) => (
<Sum key={id} label={centreName(id)}>
{TEAMS.filter((team) => team.costCentre === id).map((team) => (
<Given
key={team.name}
label={team.name}
value={{ heads: team.headcount, fte: team.fte, cost: team.monthlyCost }}
/>
))}
</Sum>
))}
</Sum>
))}
</Sum>
</Calculation>
);
}
density="compact" closes up the head and every metric's column with the lines; a note stays beneath its label, and the figures move beneath the labels by the same measure as in a regular report.
import { Calculation, Given, Sum } from "@umriss-ui/calculation";
import type { Metric } from "@umriss-ui/calculation";
const METRICS: Metric[] = [
{ id: "heads", label: "Headcount", unit: "HC" },
{ id: "fte", label: "Full-time equivalents", unit: "FTE", decimals: 1 },
];
export default function CompactReport() {
return (
<Calculation aria-label="Staff of Tidewell, 17 March" metrics={METRICS} density="compact">
<Sum label="Tidewell">
<Sum label="Engineering">
<Given label="Web team" value={{ heads: 31, fte: 27.5 }} />
<Given label="Apps team" value={{ heads: 22, fte: 20 }} />
<Given label="Platform team" value={{ heads: 18, fte: 15.8 }} source="HR system" />
<Given label="Quality assurance" value={{ heads: 25, fte: 21.2 }} />
</Sum>
<Sum label="Customer service">
<Given label="Service desk" value={{ heads: 40, fte: 31.6 }} />
<Given label="Returns" value={{ heads: 18, fte: 14.1 }} />
<Given label="Student staff" value={{ heads: 6, fte: null }} explanation="FTE are not recorded for student staff" />
</Sum>
<Given label="Administration" value={{ heads: 12, fte: 10.4 }} />
</Sum>
</Calculation>
);
}
Quotient of two givensTable from @umriss-ui/tableThe keys of Calculation apply here.
Metric| Name | Type | Default | Description |
|---|---|---|---|
idrequired | string | — | The key of this metric's number in every value object.Shown in: Headcount and full-time equivalents, A number one metric does not have, Team, cost centre, business line and 5 more |
labelrequired | string | — | The metric's name, in the head above its column and in each row's
sentence. Shown in: Headcount and full-time equivalents, A number one metric does not have, Team, cost centre, business line and 5 more |
unit | string | — | A label written after the number where a result closes, and beneath the
metric's name in the head. Never converted and never checked. Shown in: Headcount and full-time equivalents, A number one metric does not have, Team, cost centre, business line and 5 more |
decimals | number | a given as it was given, at most two for a derived number | Fixed number of fraction digits as shown, for every quantity of this
metric. Shown in: Headcount and full-time equivalents, A number one metric does not have, Team, cost centre, business line and 5 more |
Product, Quotient, Times and DividedBy fail on the first render, since a factor would need a unit in every metric.value.What umriss deliberately does not build, and why: ADR-0032.