ibcs-react

Report cookbook

97 ready-made business reports and dashboards across seven domains - each a live mini-report built from one to four ibcs-react components, with copy-pasteable source.

97 ready-made business reports and dashboards across seven domains, each a live mini-report built from one to four ibcs-react components. Figures are fictitious and deliberately varied (long and short labels; big, small and negative numbers; sparse and dense series), so the collection doubles as a visual stress test.

Every recipe carries a who / what / when line, the live report and its source. One scenario-keyed model (AC / PY / PL / FC) feeds tables, charts and KPI cards alike - switching report type is mostly choosing the component, not reshaping the numbers. For the notation rules behind the marks, see IBCS in practice; for the data shapes, see the data model.

Shared shorthands

To keep each snippet to a line or two, the samples below reuse a handful of local shorthands - datum builders, format presets and a width budget - defined once here:

import { KpiCard, Sparkline } from "ibcs-react";

const CARD_W = 560; // width budget every chart is sized to

// format presets
const fM = { compact: true, decimals: 1 } as const; // currency in millions
const fK = { compact: true } as const; // compact, integer-ish
const fN = { compact: false } as const; // plain counts / scores
const fN1 = { compact: false, decimals: 1 } as const;
const fPct1 = { compact: false, decimals: 1 } as const;

// datum builders - a `category` plus optional AC / PY / PL / FC
const C = (category, AC, PY, PL) => ({
  category,
  AC,
  ...(PY !== undefined ? { PY } : {}),
  ...(PL !== undefined ? { PL } : {}),
});
const L = (category, o) => ({ category, ...o });
const S = (category, AC, PY, PL, higherIsBetter) => ({
  category,
  AC,
  ...(PY !== undefined ? { PY } : {}),
  ...(PL !== undefined ? { PL } : {}),
  ...(higherIsBetter === false ? { higherIsBetter: false } : {}),
});
const W = (category, value, flow, higherIsBetter) => ({
  category,
  value,
  ...(flow ? { flow } : {}),
  ...(higherIsBetter === false ? { higherIsBetter: false } : {}),
});

// a DataTable value + ΔPY(bar) + ΔPY%(pin) column trio for one measure
const varCols = (measure, label, higherIsBetter) => [
  { key: measure, label, kind: "value", scenario: "AC" },
  {
    key: measure + "_d",
    label: "ΔPY",
    kind: "variance",
    measure,
    base: "PY",
    mode: "abs",
    mark: "bar",
    ...(higherIsBetter === false ? { higherIsBetter: false } : {}),
  },
  {
    key: measure + "_p",
    label: "ΔPY%",
    kind: "variance",
    measure,
    base: "PY",
    mode: "pct",
    mark: "pin",
    ...(higherIsBetter === false ? { higherIsBetter: false } : {}),
  },
];

// KpiStrip / SparkTile are thin local layout wrappers around KpiCard / Sparkline.

Nothing in the library requires them: every builder just returns a plain object, so you can inline your own data or map it straight out of an API response.

Finance & accounting

Statements, bridges, variance and working-capital views - the backbone of the monthly close. 18 recipes.

Components used here: AreaChart, ComboChart, DataTable, KpiCard, LineChart, StackedChart, StatementTable, StructureChart, TreeChart, TrendChart, VarianceColumnChart, WaterfallChart.

Income statement (waterfall)

Northwind Materials · € m · FY26 vs PY/PL

 PYACΔPYΔPY%
Product revenue16.1M17.2M+1.1M+6.8
Service and other revenue9.5M12.9M+3.4M+35.8
=Revenue25.6M30.1M+4.5M+17.6
−Product cost3.1M3.5M+400K+12.9
−Service and other costs5.3M6.2M+900K+17.0
=Gross margin17.2M20.4M+3.2M+18.6
−Research and development3.5M3.9M+400K+11.4
−Sales and marketing4.3M4.8M+500K+11.6
−General and administrative1.4M1.3M-100K-7.1
−Restructuring306K0-306K-100.0
=Operating income7.7M10.4M+2.7M+35.2
import { StatementTable } from "ibcs-react";

<StatementTable lines={sampleStatementFlat.slice(0, 11)} waterfallWidth={150} format={fM} />;

Balance sheet

Northwind Materials · € m · point-in-time

 PYACΔPYΔPY%
Current assets14.8M16.7M+1.9M+12.8
Cash and equivalents6.5M8.2M+1.7M+26.2
Accounts receivable4.9M5.4M+500K+10.2
Inventory3.4M3.1M-300K-8.8
Non-current assets19.2M20.3M+1.1M+5.7
=Total assets34M37M+3M+8.8
Current liabilities6.6M6.6M00.0
Accounts payable3.6M4.1M+500K+13.9
Short-term debt3M2.5M-500K-16.7
Non-current liabilities10.7M10.4M-300K-2.8
Long-term debt9.5M9M-500K-5.3
Deferred tax & other1.2M1.4M+200K+16.7
=Total liabilities17.3M17M-300K-1.7
Shareholders’ equity16.7M20M+3.3M+19.8
Share capital5M5M00.0
Retained earnings11.7M15M+3.3M+28.2
=Total liabilities & equity34M37M+3M+8.8
import { StatementTable } from "ibcs-react";

<StatementTable lines={sampleBalanceSheet} mode="stock" waterfallWidth={140} format={fM} />;

Cash flow bridge

Helios Foods · € m · opening → closing cash

0+9-5-2-01Opening cashOperatingInvestingFinancingFX effectClosing cash
Bridge of actual contributions - data table
ContributionRunning total
Opening cash00
Operating+99
Investing-54
Financing-21
FX effect-01
Closing cash11
import { WaterfallChart } from "ibcs-react";

<WaterfallChart
  data={[
    W("Opening cash", 4.2, "result"),
    W("Operating", 8.6, "add"),
    W("Investing", 5.1, "subtract", false),
    W("Financing", 2.3, "subtract", false),
    W("FX effect", 0.2, "subtract", false),
    W("Closing cash", 5.2, "result"),
  ]}
  scenario="AC"
  width={CARD_W}
  height={220}
  format={fM}
/>;

P&L bridge - PY → AC operating income

Helios Foods · € m · effect decomposition

0+2+1-0-1-02PY op.…VolumePriceMixInput costOpexAC op. in…
Bridge of actual contributions - data table
ContributionRunning total
PY op. income00
Volume+22
Price+13
Mix-03
Input cost-12
Opex-02
AC op. income22
import { WaterfallChart } from "ibcs-react";

<WaterfallChart
  data={[
    W("PY op. income", 7.7, "result"),
    W("Volume", 1.9, "add"),
    W("Price", 1.4, "add"),
    W("Mix", 0.4, "subtract", false),
    W("Input cost", 0.9, "subtract", false),
    W("Opex", 0.1, "subtract", false),
    W("AC op. income", 10.4, "result"),
  ]}
  scenario="AC"
  width={CARD_W}
  height={220}
  format={fM}
/>;

Budget vs actual - quarterly revenue

Aurora Retail · € m · AC vs PL

7Q17Q28Q38Q4+0+0+0+1
AC versus PL - data table
ACPLΔPLΔPL%
Q177+0+4.6%
Q277+0+4.3%
Q387+0+2.7%
Q488+1+10.5%
import { VarianceColumnChart } from "ibcs-react";

<VarianceColumnChart
  data={[
    C("Q1", 6.8, undefined, 6.5),
    C("Q2", 7.3, undefined, 7.0),
    C("Q3", 7.6, undefined, 7.4),
    C("Q4", 8.4, undefined, 7.6),
  ]}
  comparison="PL"
  width={CARD_W}
  height={210}
  format={fM}
/>;

Revenue variance analysis

Aurora Retail · € m · 13 periods, AC vs PY

ACPYPL2.3M2.4M2.6M2.5M2.6M2.7M2.7M2.8M2.9M3M3.1M3.1M3.2MP1P2P3P4P5P6P7P8P9P10P11P12P13+150K+220K+170K+60K+170K+210K+80K+170K+230K+190K+190K+170K+180K
Trend versus PY - data table
CurrentPYPLΔPYΔPY%
P12.3M2.2M2.3M+150K+7.0%
P22.4M2.2M2.4M+220K+10.0%
P32.6M2.4M2.5M+170K+7.1%
P42.5M2.4M2.5M+60K+2.5%
P52.6M2.5M2.6M+170K+6.9%
P62.7M2.5M2.6M+210K+8.4%
P72.7M2.6M2.7M+80K+3.1%
P82.8M2.6M2.7M+170K+6.5%
P92.9M2.7M2.9M+230K+8.5%
P10 (FC)3M2.8M2.9M+190K+6.8%
P11 (FC)3.1M2.9M3M+190K+6.6%
P12 (FC)3.1M3M3.1M+170K+5.8%
P13 (FC)3.2M3M3.2M+180K+6.0%
import { TrendChart } from "ibcs-react";

<TrendChart data={sampleMonthlyTrend} comparison="PY" width={CARD_W} height={236} format={fK} />;

Gross-margin walk

Cobalt Devices · € m · PY → AC

0+2+2-0-03PY gross marg…VolumePrice/mixMaterial costLabourAC gross marg…
Bridge of actual contributions - data table
ContributionRunning total
PY gross margin00
Volume+22
Price/mix+24
Material cost-03
Labour-03
AC gross margin33
import { WaterfallChart } from "ibcs-react";

<WaterfallChart
  data={[
    W("PY gross margin", 17.2, "result"),
    W("Volume", 2.1, "add"),
    W("Price/mix", 1.7, "add"),
    W("Material cost", 0.4, "subtract", false),
    W("Labour", 0.2, "subtract", false),
    W("AC gross margin", 20.4, "result"),
  ]}
  scenario="AC"
  width={CARD_W}
  height={220}
  format={fM}
/>;

Operating-expense breakdown

Cobalt Devices · € m · AC vs PY share

Sales & market…5+142%Research & dev…4+034%General & admin1-011%Customer suppo…1+08%Facilities1-05%Total12+1100%
Composition versus PY - data table
ValuePYΔPYShare
Sales & marketing54+142%
Research & development44+034%
General & admin11-011%
Customer support11+08%
Facilities11-05%
Total1211+1100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Sales & marketing", 4.8, 4.3, undefined, false),
    S("Research & development", 3.9, 3.5, undefined, false),
    S("General & admin", 1.3, 1.4, undefined, false),
    S("Customer support", 0.9, 0.8, undefined, false),
    S("Facilities", 0.6, 0.7, undefined, false),
  ]}
  comparison="PY"
  higherIsBetter={false}
  width={CARD_W}
  height={220}
  labelWidth={120}
  format={fM}
/>;

Working-capital metrics

Northwind Materials · days · AC vs PY

DSO
47-5-9.6%vs PY
DIO
61+3+5.2%vs PY
DPO
39+4+11.4%vs PY
Cash cycle
69-6-8.0%vs PY
import { KpiCard } from "ibcs-react"; // KpiStrip is a small local wrapper around KpiCard

<KpiStrip
  items={[
    {
      label: "DSO",
      values: { AC: 47, PY: 52 },
      comparisons: ["PY"],
      higherIsBetter: false,
      format: fN,
    },
    {
      label: "DIO",
      values: { AC: 61, PY: 58 },
      comparisons: ["PY"],
      higherIsBetter: false,
      format: fN,
    },
    { label: "DPO", values: { AC: 39, PY: 35 }, comparisons: ["PY"], format: fN },
    {
      label: "Cash cycle",
      values: { AC: 69, PY: 75 },
      comparisons: ["PY"],
      higherIsBetter: false,
      format: fN,
    },
  ]}
/>;

AR aging by segment

Aurora Retail · € k · open receivables

Enterprise1.3KMid-market810SMB580Current1-3031-6061+
Stacked bars - data table
Current1-3031-6061+Total
Enterprise820210901401.3K
Mid-market5401607040810
SMB3101205595580
import { StackedChart } from "ibcs-react";

<StackedChart
  data={[
    { category: "Enterprise", values: { cur: 820, d30: 210, d60: 90, d90: 140 } },
    { category: "Mid-market", values: { cur: 540, d30: 160, d60: 70, d90: 40 } },
    { category: "SMB", values: { cur: 310, d30: 120, d60: 55, d90: 95 } },
  ]}
  series={[
    { key: "cur", label: "Current" },
    { key: "d30", label: "1-30" },
    { key: "d60", label: "31-60" },
    { key: "d90", label: "61+" },
  ]}
  orientation="bar"
  width={CARD_W}
  height={210}
  format={fK}
/>;

Revenue by region

Northwind Materials · € m · AC vs PY

North America12.4M+1.3M41%Europe8.9M+900K30%Asia Pacific5.6M+1.4M19%Latin America2.1M+600K7%Middle East & Af…1.1M+300K4%Total30.1M+4.5M100%
Composition versus PY - data table
ValuePYΔPYShare
North America12.4M11.1M+1.3M41%
Europe8.9M8M+900K30%
Asia Pacific5.6M4.2M+1.4M19%
Latin America2.1M1.5M+600K7%
Middle East & Africa1.1M800K+300K4%
Total30.1M25.6M+4.5M100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={sampleRevenueStructure}
  comparison="PY"
  width={CARD_W}
  height={230}
  labelWidth={130}
  format={fM}
/>;

EBITDA trend

Helios Foods · € m · monthly, AC vs PL line

AC 3PL 3JanFebMarAprMayJunJulAug+0+00+00+0+0+0
Line chart of 2 series - data table
ACPLΔPLΔPL%
Jan22+0+5.0%
Feb22+0+9.5%
Mar2200.0%
Apr32+0+8.3%
May3300.0%
Jun33+0+11.5%
Jul33+0+10.7%
Aug33+0+3.4%
import { LineChart } from "ibcs-react";

<LineChart
  data={[
    L("Jan", { AC: 2.1, PL: 2.0 }),
    L("Feb", { AC: 2.3, PL: 2.1 }),
    L("Mar", { AC: 2.2, PL: 2.2 }),
    L("Apr", { AC: 2.6, PL: 2.4 }),
    L("May", { AC: 2.5, PL: 2.5 }),
    L("Jun", { AC: 2.9, PL: 2.6 }),
    L("Jul", { AC: 3.1, PL: 2.8 }),
    L("Aug", { AC: 3.0, PL: 2.9 }),
  ]}
  comparison="PL"
  variance="abs"
  width={CARD_W}
  height={236}
  format={fK}
/>;

Multi-year P&L statement

Vector Software · € m · 2012-2015 (wide → scroll)

 2012201320142015
Software revenue
467
453
543
520
620
640
700
710
Support revenue
99
87
132
120
150
158
170
175
Consulting revenue
145
121
231
150
240
252
260
265
Revenue
711
661
906
790
1,010
1,050
1,130
1,150
Cost of sales
282
231
340
300
360
372
400
405
Gross profit
429
430
566
490
650
678
730
745
Research and development expenses
79
78
91
88
98
104
110
112
Selling and general administrative expenses
34
45
41
44
48
52
55
56
import { DataTable } from "ibcs-react";

<div style={{ minWidth: 560 }}>
  <DataTable columns={tableT03Columns} rows={sampleTableT03.slice(0, 8)} format={fN} />
</div>;

Cost-centre variance

Cobalt Devices · € k · AC vs PY

 
Engineering
1,840
+220+13.6
Sales
1,370
+190+16.1
Operations
960
-50-5.0
G&A
540
-20-3.6
IT & security
430
+130+43.3
Total
5,140
+470+10.1
import { DataTable } from "ibcs-react";

<DataTable
  columns={varCols("spend", "Spend", false)}
  rows={[
    { id: "eng", label: "Engineering", values: { spend: { AC: 1840, PY: 1620 } } },
    { id: "ops", label: "Operations", values: { spend: { AC: 960, PY: 1010 } } },
    { id: "sales", label: "Sales", values: { spend: { AC: 1370, PY: 1180 } } },
    { id: "ga", label: "G&A", values: { spend: { AC: 540, PY: 560 } } },
    { id: "it", label: "IT & security", values: { spend: { AC: 430, PY: 300 } } },
  ]}
  format={fN}
  showTotals
  defaultSort={{ key: "spend", dir: "desc" }}
/>;

Capex vs depreciation

Northwind Materials · € m · invest vs D&A %

Capex (€ m)D&A cover %024602040604FY225FY235FY246FY256FY267164785973
Combination chart data table
ACPYD&A cover %
FY224n/a71
FY235n/a64
FY245n/a78
FY256n/a59
FY266n/a73
import { ComboChart } from "ibcs-react";

<ComboChart
  data={[C("FY22", 4.1), C("FY23", 5.3), C("FY24", 4.8), C("FY25", 6.2), C("FY26", 5.5)]}
  secondary={[
    { category: "FY22", value: 71 },
    { category: "FY23", value: 64 },
    { category: "FY24", value: 78 },
    { category: "FY25", value: 59 },
    { category: "FY26", value: 73 },
  ]}
  primaryLabel="Capex (€ m)"
  secondaryLabel="D&A cover %"
  secondaryFormat={fPct1}
  width={CARD_W}
  height={220}
  format={fK}
/>;

Free cash flow

Helios Foods · € m · monthly with PY baseline

AC 2PY 1JanFebMarAprMayJun
Area chart of AC - data table
ACPY
Jan11
Feb11
Mar-00
Apr11
May11
Jun21
import { AreaChart } from "ibcs-react";

<AreaChart
  data={[
    L("Jan", { AC: 0.8, PY: 0.6 }),
    L("Feb", { AC: 1.1, PY: 0.9 }),
    L("Mar", { AC: -0.4, PY: 0.2 }),
    L("Apr", { AC: 0.9, PY: 0.7 }),
    L("May", { AC: 1.4, PY: 1.0 }),
    L("Jun", { AC: 1.7, PY: 1.3 }),
  ]}
  scenario="AC"
  baseline="PY"
  width={CARD_W}
  height={210}
  format={fK}
/>;

Return-on-assets driver tree

Northwind Materials · ratio decomposition

÷Return on assets0+0 vs PYNet income31M+2.6M vs PYTotal assets250M+9.3M vs PY
Calculation tree data table
ValuePYΔPY
Return on assets00+0
· Net income31M28.4M+2.6M
· Total assets250M240.7M+9.3M
import { TreeChart } from "ibcs-react";

<TreeChart
  root={{
    id: "roa",
    label: "Return on assets",
    value: 0.124,
    py: 0.118,
    op: "/",
    format: { decimals: 3 },
    children: [
      { id: "ni", label: "Net income", value: 31e6, py: 28.4e6 },
      { id: "ta", label: "Total assets", value: 250e6, py: 240.7e6 },
    ],
  }}
  width={CARD_W}
  height={210}
  format={fK}
/>;

Interest-coverage & leverage

Northwind Materials · ratios · AC vs PY

Interest cover
×6.4+1.3+25.5%vs PY
Net debt / EBITDA
×1.8-0.5-21.7%vs PY
Current ratio
×1.9+0.3+18.7%vs PY
import { KpiCard } from "ibcs-react"; // KpiStrip is a small local wrapper around KpiCard

<KpiStrip
  items={[
    {
      label: "Interest cover",
      values: { AC: 6.4, PY: 5.1 },
      comparisons: ["PY"],
      format: { ...fN1, currency: "×" },
    },
    {
      label: "Net debt / EBITDA",
      values: { AC: 1.8, PY: 2.3 },
      comparisons: ["PY"],
      higherIsBetter: false,
      format: { ...fN1, currency: "×" },
    },
    {
      label: "Current ratio",
      values: { AC: 1.9, PY: 1.6 },
      comparisons: ["PY"],
      format: { ...fN1, currency: "×" },
    },
  ]}
/>;

Sales

Pipeline, attainment, channel and account performance, all on a zero baseline with impact colour. 14 recipes.

Components used here: DataTable, LineChart, MiniVarianceMultiples, ScatterChart, StackedChart, StructureChart, TrendChart, VarianceColumnChart.

Revenue by product line

Aurora Retail · € m · AC vs PY

Apparel11+137%Footwear7-125%Accessories5+117%Home & living4+113%Outdoor gear3-19%Total30+3100%
Composition versus PY - data table
ValuePYΔPYShare
Apparel1110+137%
Footwear78-125%
Accessories54+117%
Home & living43+113%
Outdoor gear33-19%
Total3028+3100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Apparel", 11.2, 9.8),
    S("Footwear", 7.4, 7.9),
    S("Accessories", 5.1, 4.2),
    S("Home & living", 3.8, 2.6),
    S("Outdoor gear", 2.6, 3.1),
  ]}
  comparison="PY"
  width={CARD_W}
  height={220}
  labelWidth={120}
  format={fM}
/>;

Revenue by channel

Aurora Retail · € m · channel mix over quarters

8Q18Q29Q39Q4WholesaleRetailOnline
Stacked columns - data table
OnlineRetailWholesaleTotal
Q14218
Q25228
Q35229
Q46219
import { StackedChart } from "ibcs-react";

<StackedChart
  data={[
    { category: "Q1", values: { online: 4.1, retail: 2.4, wholesale: 1.3 } },
    { category: "Q2", values: { online: 4.6, retail: 2.2, wholesale: 1.5 } },
    { category: "Q3", values: { online: 5.0, retail: 2.1, wholesale: 1.6 } },
    { category: "Q4", values: { online: 5.8, retail: 2.0, wholesale: 1.4 } },
  ]}
  series={[
    { key: "online", label: "Online" },
    { key: "retail", label: "Retail" },
    { key: "wholesale", label: "Wholesale" },
  ]}
  orientation="column"
  width={CARD_W}
  height={210}
  format={fK}
  highlight="online"
/>;

Sales-rep leaderboard

Vector Software · € k · bookings AC vs PY

 
Dana Whitfield
1,240
+260+26.5
Marco Pereira
1,110
-80-6.7
Aisha Karim
980
+260+36.1
Tom Becker
870
-40-4.4
Lena Ostrowski
760
+220+40.7
Total
4,960
+620+14.3
import { DataTable } from "ibcs-react";

<DataTable
  columns={varCols("book", "Bookings")}
  rows={[
    { id: "r1", label: "Dana Whitfield", values: { book: { AC: 1240, PY: 980 } } },
    { id: "r2", label: "Marco Pereira", values: { book: { AC: 1110, PY: 1190 } } },
    { id: "r3", label: "Aisha Karim", values: { book: { AC: 980, PY: 720 } } },
    { id: "r4", label: "Tom Becker", values: { book: { AC: 870, PY: 910 } } },
    { id: "r5", label: "Lena Ostrowski", values: { book: { AC: 760, PY: 540 } } },
  ]}
  format={fN}
  showTotals
  defaultSort={{ key: "book", dir: "desc" }}
/>;

Sales pipeline funnel

Vector Software · count · stage drop-off

Leads4,20055%Qualified1,85024%Proposal94012%Negotiation4105%Closed won1882%Total7,588100%
Composition versus PY - data table
ValuePYShare
Leads4,200n/a55%
Qualified1,850n/a24%
Proposal940n/a12%
Negotiation410n/a5%
Closed won188n/a2%
Total7,588n/a100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Leads", 4200),
    S("Qualified", 1850),
    S("Proposal", 940),
    S("Negotiation", 410),
    S("Closed won", 188),
  ]}
  comparison="PY"
  showComparison={false}
  variance="none"
  width={CARD_W}
  height={210}
  labelWidth={104}
  format={fN}
/>;

Win rate by region

Vector Software · % · AC vs PY

 
North America
28
+4
Europe
31
-2
Asia Pacific
22
+4
Latin America
19
-2
import { DataTable } from "ibcs-react";

<DataTable
  columns={[
    { key: "win", label: "Win %", kind: "value", scenario: "AC" },
    {
      key: "win_d",
      label: "ΔPY",
      kind: "variance",
      measure: "win",
      base: "PY",
      mode: "abs",
      mark: "bar",
    },
  ]}
  rows={[
    { id: "na", label: "North America", values: { win: { AC: 28, PY: 24 } } },
    { id: "eu", label: "Europe", values: { win: { AC: 31, PY: 33 } } },
    { id: "apac", label: "Asia Pacific", values: { win: { AC: 22, PY: 18 } } },
    { id: "latam", label: "Latin America", values: { win: { AC: 19, PY: 21 } } },
  ]}
  format={fN}
/>;

Quota attainment by team

Vector Software · % · AC vs target (PL=100)

112Enterprise94Mid-market103SMB88Channel121Public+12-6+3-12+21
AC versus PL - data table
ACPLΔPLΔPL%
Enterprise112100+12+12.0%
Mid-market94100-6-6.0%
SMB103100+3+3.0%
Channel88100-12-12.0%
Public121100+21+21.0%
import { VarianceColumnChart } from "ibcs-react";

<VarianceColumnChart
  data={[
    C("Enterprise", 112, undefined, 100),
    C("Mid-market", 94, undefined, 100),
    C("SMB", 103, undefined, 100),
    C("Channel", 88, undefined, 100),
    C("Public", 121, undefined, 100),
  ]}
  comparison="PL"
  width={CARD_W}
  height={210}
  format={fN}
/>;

Bookings vs target

Vector Software · € m · monthly AC vs PL

ACPYPL12222223JanFebMarAprMayJunJulAug-0+0+0-0+0+0+0+0
Trend versus PL - data table
CurrentPYPLΔPLΔPL%
Jan1n/a1-0-7.7%
Feb2n/a1+0+7.1%
Mar2n/a2+0+12.5%
Apr2n/a2-0-5.9%
May2n/a2+0+11.1%
Jun2n/a2+0+15.0%
Jul (FC)2n/a2+0+4.8%
Aug (FC)3n/a2+0+8.7%
import { TrendChart } from "ibcs-react";

<TrendChart
  data={[
    L("Jan", { AC: 1.2, PL: 1.3 }),
    L("Feb", { AC: 1.5, PL: 1.4 }),
    L("Mar", { AC: 1.8, PL: 1.6 }),
    L("Apr", { AC: 1.6, PL: 1.7 }),
    L("May", { AC: 2.0, PL: 1.8 }),
    L("Jun", { AC: 2.3, PL: 2.0 }),
    L("Jul", { FC: 2.2, PL: 2.1 }),
    L("Aug", { FC: 2.5, PL: 2.3 }),
  ]}
  comparison="PL"
  width={CARD_W}
  height={236}
  format={fK}
/>;

Discount vs deal size

Vector Software · won deals this quarter

0102030405060051015202530Deal size (€ k)Discount %EnterpriseMidSMB
Scatter plot data table
Deal size (€ k)Discount %Group
Point 1128Enterprise
Point 24522Enterprise
Point 33015Mid
Point 484SMB
Point 56031Enterprise
Point 6229Mid
Point 752SMB
Point 83818Mid
Point 9156SMB
Point 105227Enterprise
import { ScatterChart } from "ibcs-react";

<ScatterChart
  data={[
    { x: 12, y: 8, group: "Enterprise" },
    { x: 45, y: 22, group: "Enterprise" },
    { x: 30, y: 15, group: "Mid" },
    { x: 8, y: 4, group: "SMB" },
    { x: 60, y: 31, group: "Enterprise" },
    { x: 22, y: 9, group: "Mid" },
    { x: 5, y: 2, group: "SMB" },
    { x: 38, y: 18, group: "Mid" },
    { x: 15, y: 6, group: "SMB" },
    { x: 52, y: 27, group: "Enterprise" },
  ]}
  xLabel="Deal size (€ k)"
  yLabel="Discount %"
  width={CARD_W}
  height={220}
  format={fN}
/>;

New vs existing business

Aurora Retail · € m · quarterly split

9Q19Q210Q310Q4RenewalExpansionNew
Stacked columns - data table
NewExpansionRenewalTotal
Q13249
Q23249
Q332410
Q443410
import { StackedChart } from "ibcs-react";

<StackedChart
  data={[
    { category: "Q1", values: { neww: 3.1, expand: 1.8, renew: 3.9 } },
    { category: "Q2", values: { neww: 3.4, expand: 2.0, renew: 3.9 } },
    { category: "Q3", values: { neww: 2.9, expand: 2.4, renew: 4.3 } },
    { category: "Q4", values: { neww: 3.8, expand: 2.6, renew: 4.0 } },
  ]}
  series={[
    { key: "neww", label: "New" },
    { key: "expand", label: "Expansion" },
    { key: "renew", label: "Renewal" },
  ]}
  orientation="column"
  width={CARD_W}
  height={210}
  format={fK}
/>;

Average deal size trend

Vector Software · € k · 12 months (dense)

AC 28PY 27JanFebMarAprMayJunJulAugSepOctNovDec
Line chart of 2 series - data table
ACPY
Jan1816
Feb2217
Mar2518
Apr2719
May2720
Jun2521
Jul2322
Aug2123
Sep2024
Oct2125
Nov2426
Dec2827
import { LineChart } from "ibcs-react";

<LineChart
  data={["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"].map(
    (m, i) => L(m, { AC: 18 + Math.round(6 * Math.sin(i / 1.8)) + i, PY: 16 + i }),
  )}
  comparison="PY"
  width={CARD_W}
  height={210}
  format={fN}
/>;

Top accounts by revenue

Aurora Retail · € k · AC vs PY (sortable)

 
Brightline Logistics Group
2,140
+260+13.8
Meridian Health Systems
1,760
-160-8.3
Quantum Robotics
1,410
+420+42.4
Solstice Energy
1,180
-60-4.8
Tideway Foods
940
+180+23.7
Total
7,430
+640+9.4
import { DataTable } from "ibcs-react";

<DataTable
  columns={varCols("rev", "Revenue")}
  rows={[
    { id: "a1", label: "Brightline Logistics Group", values: { rev: { AC: 2140, PY: 1880 } } },
    { id: "a2", label: "Meridian Health Systems", values: { rev: { AC: 1760, PY: 1920 } } },
    { id: "a3", label: "Quantum Robotics", values: { rev: { AC: 1410, PY: 990 } } },
    { id: "a4", label: "Solstice Energy", values: { rev: { AC: 1180, PY: 1240 } } },
    { id: "a5", label: "Tideway Foods", values: { rev: { AC: 940, PY: 760 } } },
  ]}
  format={fN}
  showTotals
  defaultSort={{ key: "rev", dir: "desc" }}
/>;

Regional bookings - small multiples

Vector Software · € m · AC vs PY

North America-0Q1-0Q2+0Q3+1Q4
Europe+0Q1+0Q2+0Q3+0Q4
Asia Pacific+0Q1+0Q2+1Q3+1Q4
Latin America-0Q10Q2-0Q3-0Q4
Variance versus PY - data table
ACPYΔPY
North America - Q144-0
North America - Q244-0
North America - Q354+0
North America - Q455+1
Europe - Q133+0
Europe - Q233+0
Europe - Q343+0
Europe - Q444+0
Asia Pacific - Q121+0
Asia Pacific - Q222+0
Asia Pacific - Q322+1
Asia Pacific - Q432+1
Latin America - Q111-0
Latin America - Q2110
Latin America - Q311-0
Latin America - Q411-0
import { MiniVarianceMultiples } from "ibcs-react";

<div style={{ width: CARD_W }}>
  <MiniVarianceMultiples
    groups={[
      {
        label: "North America",
        data: [C("Q1", 4.2, 4.4), C("Q2", 4.0, 4.3), C("Q3", 4.5, 4.2), C("Q4", 5.1, 4.6)],
      },
      {
        label: "Europe",
        data: [C("Q1", 3.1, 2.8), C("Q2", 3.4, 3.0), C("Q3", 3.6, 3.2), C("Q4", 3.9, 3.5)],
      },
      {
        label: "Asia Pacific",
        data: [C("Q1", 1.8, 1.4), C("Q2", 2.0, 1.6), C("Q3", 2.2, 1.7), C("Q4", 2.6, 1.9)],
      },
      {
        label: "Latin America",
        data: [C("Q1", 0.9, 1.1), C("Q2", 1.0, 1.0), C("Q3", 1.1, 1.2), C("Q4", 0.8, 0.9)],
      },
    ]}
    comparison="PY"
    columns={2}
    format={fK}
  />
</div>;

Discount analysis by tier

Aurora Retail · % · AC vs PY (cost-like)

0List8Tier 114Tier 222Tier 341Clearance0+2+3-3+3
AC versus PY - data table
ACPYΔPYΔPY%
List000n/a
Tier 186+2+33.3%
Tier 21411+3+27.3%
Tier 32225-3-12.0%
Clearance4138+3+7.9%
import { VarianceColumnChart } from "ibcs-react";

<VarianceColumnChart
  data={[
    C("List", 0, 0),
    C("Tier 1", 8, 6),
    C("Tier 2", 14, 11),
    C("Tier 3", 22, 25),
    C("Clearance", 41, 38),
  ]}
  comparison="PY"
  higherIsBetter={false}
  width={CARD_W}
  height={210}
  format={fN}
/>;

Lost-deal reasons

Vector Software · count · this quarter

Price64+635%Missing feature41-822%Lost to incumb…33+318%No decision28+615%Timing17-29%Total183+5100%
Composition versus PY - data table
ValuePYΔPYShare
Price6458+635%
Missing feature4149-822%
Lost to incumbent3330+318%
No decision2822+615%
Timing1719-29%
Total183178+5100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Price", 64, 58, undefined, false),
    S("Missing feature", 41, 49, undefined, false),
    S("Lost to incumbent", 33, 30, undefined, false),
    S("No decision", 28, 22, undefined, false),
    S("Timing", 17, 19, undefined, false),
  ]}
  comparison="PY"
  higherIsBetter={false}
  width={CARD_W}
  height={210}
  labelWidth={120}
  format={fN}
/>;

Marketing

Funnels, CAC/LTV economics, channel ROI and campaign performance. 13 recipes.

Components used here: AreaChart, ComboChart, DataTable, KpiCard, LineChart, StackedChart, StructureChart, VarianceColumnChart.

Marketing funnel

Lumen Media · count · impressions → won

Impressions1.2M91%Clicks96.4K7%Leads18.2K1%MQLs7.4K1%SQLs2.9K0%Won4100%Total1.4M100%
Composition versus PY - data table
ValuePYShare
Impressions1.2Mn/a91%
Clicks96.4Kn/a7%
Leads18.2Kn/a1%
MQLs7.4Kn/a1%
SQLs2.9Kn/a0%
Won410n/a0%
Total1.4Mn/a100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Impressions", 1_240_000),
    S("Clicks", 96_400),
    S("Leads", 18_200),
    S("MQLs", 7_400),
    S("SQLs", 2_900),
    S("Won", 410),
  ]}
  comparison="PY"
  showComparison={false}
  variance="none"
  width={CARD_W}
  height={220}
  labelWidth={104}
  format={fK}
/>;

MQL → SQL conversion

Lumen Media · % · monthly AC vs PY

38Jan41Feb39Mar44Apr47May43Jun+4+5-1+6+6+1
AC versus PY - data table
ACPYΔPYΔPY%
Jan3834+4+11.8%
Feb4136+5+13.9%
Mar3940-1-2.5%
Apr4438+6+15.8%
May4741+6+14.6%
Jun4342+1+2.4%
import { VarianceColumnChart } from "ibcs-react";

<VarianceColumnChart
  data={[
    C("Jan", 38, 34),
    C("Feb", 41, 36),
    C("Mar", 39, 40),
    C("Apr", 44, 38),
    C("May", 47, 41),
    C("Jun", 43, 42),
  ]}
  comparison="PY"
  width={CARD_W}
  height={210}
  format={fN}
/>;

CAC by channel

Lumen Media · € · cost per acquisition (lower better)

Events410+3056%Paid search142+1419%Paid social98-1213%Content / SEO54-177%Referral31+34%Total735+18100%
Composition versus PY - data table
ValuePYΔPYShare
Events410380+3056%
Paid search142128+1419%
Paid social98110-1213%
Content / SEO5471-177%
Referral3128+34%
Total735717+18100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Paid search", 142, 128, undefined, false),
    S("Paid social", 98, 110, undefined, false),
    S("Events", 410, 380, undefined, false),
    S("Content / SEO", 54, 71, undefined, false),
    S("Referral", 31, 28, undefined, false),
  ]}
  comparison="PY"
  higherIsBetter={false}
  width={CARD_W}
  height={220}
  labelWidth={120}
  format={fN}
/>;

LTV : CAC & payback

Lumen Media · ratio / months · AC vs PY

LTV : CAC
×4.2+0.6+16.7%vs PY
CAC payback
11 mo-3-21.4%vs PY
Blended CAC
€96-8-7.7%vs PY
import { KpiCard } from "ibcs-react"; // KpiStrip is a small local wrapper around KpiCard

<KpiStrip
  items={[
    {
      label: "LTV : CAC",
      values: { AC: 4.2, PY: 3.6 },
      comparisons: ["PY"],
      format: { ...fN1, currency: "×" },
    },
    {
      label: "CAC payback",
      values: { AC: 11, PY: 14 },
      comparisons: ["PY"],
      higherIsBetter: false,
      format: { ...fN, suffix: " mo" },
    },
    {
      label: "Blended CAC",
      values: { AC: 96, PY: 104 },
      comparisons: ["PY"],
      higherIsBetter: false,
      format: { ...fN, currency: "€" },
    },
  ]}
/>;

Channel ROI

Lumen Media · € k · spend vs return (sortable)

 
Content
90
560
6.2
Paid search
210
820
3.9
Paid social
180
540
3
Events
320
410
1.3
import { DataTable } from "ibcs-react";

<DataTable
  columns={[
    { key: "spend", label: "Spend", kind: "value", scenario: "AC" },
    { key: "ret", label: "Return", kind: "value", scenario: "AC" },
    { key: "roi", label: "ROI×", kind: "value", scenario: "AC", format: fN1 },
  ]}
  rows={[
    {
      id: "ps",
      label: "Paid search",
      values: { spend: { AC: 210 }, ret: { AC: 820 }, roi: { AC: 3.9 } },
    },
    {
      id: "so",
      label: "Paid social",
      values: { spend: { AC: 180 }, ret: { AC: 540 }, roi: { AC: 3.0 } },
    },
    {
      id: "ev",
      label: "Events",
      values: { spend: { AC: 320 }, ret: { AC: 410 }, roi: { AC: 1.3 } },
    },
    {
      id: "co",
      label: "Content",
      values: { spend: { AC: 90 }, ret: { AC: 560 }, roi: { AC: 6.2 } },
    },
  ]}
  format={fN}
  defaultSort={{ key: "roi", dir: "desc" }}
/>;

Web traffic trend

Lumen Media · k sessions · AC vs PY

AC 191PY 152W1W2W3W4W5W6W7W8
Area chart of AC - data table
ACPY
W1120110
W2137116
W3138122
W4155128
W5156134
W6173140
W7174146
W8191152
import { AreaChart } from "ibcs-react";

<AreaChart
  data={["W1", "W2", "W3", "W4", "W5", "W6", "W7", "W8"].map((w, i) =>
    L(w, { AC: 120 + i * 9 + (i % 2 ? 8 : 0), PY: 110 + i * 6 }),
  )}
  scenario="AC"
  baseline="PY"
  width={CARD_W}
  height={210}
  format={fN}
/>;

Campaign performance

Lumen Media · multi-metric · current month

 Trend
Spring launch
480,000
2.4
38
Retargeting
210,000
4.1
22
Brand always-on
920,000
0.9
61
import { DataTable } from "ibcs-react";

<DataTable
  columns={[
    { key: "imp", label: "Impr.", kind: "value", scenario: "AC" },
    { key: "ctr", label: "CTR%", kind: "value", scenario: "AC", format: fN1 },
    { key: "cpl", label: "CPL €", kind: "value", scenario: "AC" },
    { key: "spk", label: "Trend", kind: "sparkline", measure: "spk", sparkType: "bar" },
  ]}
  rows={[
    {
      id: "c1",
      label: "Spring launch",
      values: { imp: { AC: 480000 }, ctr: { AC: 2.4 }, cpl: { AC: 38 } },
      spark: { spk: [8, 12, 9, 15, 18, 14, 21] },
    },
    {
      id: "c2",
      label: "Retargeting",
      values: { imp: { AC: 210000 }, ctr: { AC: 4.1 }, cpl: { AC: 22 } },
      spark: { spk: [5, 6, 8, 7, 9, 11, 13] },
    },
    {
      id: "c3",
      label: "Brand always-on",
      values: { imp: { AC: 920000 }, ctr: { AC: 0.9 }, cpl: { AC: 61 } },
      spark: { spk: [20, 18, 19, 17, 16, 18, 15] },
    },
  ]}
  format={fN}
/>;

Email engagement

Lumen Media · % · open vs click, 8 weeks

AC 26PY 23.8W1W2W3W4W5W6W7W8
Line chart of 2 series - data table
ACPY
W12421
W22621.4
W32821.8
W42422.2
W52622.6
W62823
W72423.4
W82623.8
import { LineChart } from "ibcs-react";

<LineChart
  data={["W1", "W2", "W3", "W4", "W5", "W6", "W7", "W8"].map((w, i) =>
    L(w, { AC: 24 + (i % 3) * 2, PY: 21 + i * 0.4 }),
  )}
  comparison="PY"
  width={CARD_W}
  height={210}
  format={fN}
/>;

Spend & cost-per-lead

Lumen Media · € k / € · monthly combo

Spend (€ k)CPL (€)02040608001020304064Jan71Feb58Mar82Apr90May76Jun413847333136
Combination chart data table
ACPYCPL (€)
Jan64n/a41
Feb71n/a38
Mar58n/a47
Apr82n/a33
May90n/a31
Jun76n/a36
import { ComboChart } from "ibcs-react";

<ComboChart
  data={[C("Jan", 64), C("Feb", 71), C("Mar", 58), C("Apr", 82), C("May", 90), C("Jun", 76)]}
  secondary={[
    { category: "Jan", value: 41 },
    { category: "Feb", value: 38 },
    { category: "Mar", value: 47 },
    { category: "Apr", value: 33 },
    { category: "May", value: 31 },
    { category: "Jun", value: 36 },
  ]}
  primaryLabel="Spend (€ k)"
  secondaryLabel="CPL (€)"
  secondaryFormat={fN}
  width={CARD_W}
  height={220}
  format={fN}
/>;

Channel mix of MQLs

Lumen Media · count · quarter-over-quarter

5.9KQ16.4KQ27.2KQ3EventsContentSocialSearch
Stacked columns - data table
SearchSocialContentEventsTotal
Q12.1K1.4K1.8K6005.9K
Q22.3K1.6K2K5006.4K
Q32.2K1.9K2.4K7007.2K
import { StackedChart } from "ibcs-react";

<StackedChart
  data={[
    { category: "Q1", values: { search: 2100, social: 1400, content: 1800, events: 600 } },
    { category: "Q2", values: { search: 2300, social: 1600, content: 2000, events: 500 } },
    { category: "Q3", values: { search: 2200, social: 1900, content: 2400, events: 700 } },
  ]}
  series={[
    { key: "search", label: "Search" },
    { key: "social", label: "Social" },
    { key: "content", label: "Content" },
    { key: "events", label: "Events" },
  ]}
  orientation="column"
  width={CARD_W}
  height={210}
  format={fK}
/>;

Brand vs performance spend

Lumen Media · € k · split by half

H11.3KH21.3KBrandPerformance
Stacked bars - data table
BrandPerformanceTotal
H14208801.3K
H25107601.3K
import { StackedChart } from "ibcs-react";

<StackedChart
  data={[
    { category: "H1", values: { brand: 420, perf: 880 } },
    { category: "H2", values: { brand: 510, perf: 760 } },
  ]}
  series={[
    { key: "brand", label: "Brand" },
    { key: "perf", label: "Performance" },
  ]}
  orientation="bar"
  width={CARD_W}
  height={180}
  format={fK}
  showTotals
/>;

SEO vs paid sessions

Lumen Media · k · two-series line

AC 100PY 70JanFebMarAprMayJun
Line chart of 2 series - data table
ACPY
Jan6050
Feb6854
Mar7658
Apr8462
May9266
Jun10070
import { LineChart } from "ibcs-react";

<LineChart
  data={["Jan", "Feb", "Mar", "Apr", "May", "Jun"].map((m, i) =>
    L(m, { AC: 60 + i * 8, PY: 50 + i * 4 }),
  )}
  series={["AC", "PY"]}
  width={CARD_W}
  height={200}
  format={fN}
/>;

Landing-page conversion

Lumen Media · % · AC vs PL target

3.2Home6.8Pricing11.4Demo1.1Blog+0.2+0.8+1.4-0.4
AC versus PL - data table
ACPLΔPLΔPL%
Home3.23+0.2+6.7%
Pricing6.86+0.8+13.3%
Demo11.410+1.4+14.0%
Blog1.11.5-0.4-26.7%
import { VarianceColumnChart } from "ibcs-react";

<VarianceColumnChart
  data={[
    C("Home", 3.2, undefined, 3.0),
    C("Pricing", 6.8, undefined, 6.0),
    C("Demo", 11.4, undefined, 10.0),
    C("Blog", 1.1, undefined, 1.5),
  ]}
  comparison="PL"
  width={CARD_W}
  height={210}
  format={fN1}
/>;

Product & SaaS

Recurring-revenue, retention, engagement and adoption metrics for a subscription business. 14 recipes.

Components used here: BubbleChart, ComboChart, KpiCard, LineChart, MatrixTable, StackedChart, StructureChart, TrendChart, VarianceColumnChart, WaterfallChart.

MRR trend

Vector Software · € k · 13 periods, AC + forecast

ACPYPL2.3K2.4K2.6K2.5K2.6K2.7K2.7K2.8K2.9K3K3.1K3.1K3.2KM1M2M3M4M5M6M7M8M9M10M11M12M13+50+70+70-20+70+90-20+60+80+70+50+40+50
Trend versus PL - data table
CurrentPYPLΔPLΔPL%
M12.3Kn/a2.3K+50+2.2%
M22.4Kn/a2.4K+70+3.0%
M32.6Kn/a2.5K+70+2.8%
M42.5Kn/a2.5K-20-0.8%
M52.6Kn/a2.6K+70+2.7%
M62.7Kn/a2.6K+90+3.4%
M72.7Kn/a2.7K-20-0.7%
M82.8Kn/a2.7K+60+2.2%
M92.9Kn/a2.9K+80+2.8%
M10 (FC)3Kn/a2.9K+70+2.4%
M11 (FC)3.1Kn/a3K+50+1.7%
M12 (FC)3.1Kn/a3.1K+40+1.3%
M13 (FC)3.2Kn/a3.2K+50+1.6%
import { TrendChart } from "ibcs-react";

<TrendChart
  data={sampleMonthlyTrend.map((d, i) => ({
    category: `M${i + 1}`,
    ...(d.AC ? { AC: d.AC / 1000 } : {}),
    ...(d.FC ? { FC: d.FC / 1000 } : {}),
    PL: (d.PL ?? 0) / 1000,
  }))}
  comparison="PL"
  width={CARD_W}
  height={236}
  format={fK}
/>;

ARR bridge

Vector Software · € k · beginning → ending ARR

0+1.6K+920-310-5401.7KBeginning ARRNewExpansionContractionChurnEnding ARR
Bridge of actual contributions - data table
ContributionRunning total
Beginning ARR00
New+1.6K1.6K
Expansion+9202.6K
Contraction-3102.3K
Churn-5401.7K
Ending ARR1.7K1.7K
import { WaterfallChart } from "ibcs-react";

<WaterfallChart
  data={[
    W("Beginning ARR", 8200, "result"),
    W("New", 1640, "add"),
    W("Expansion", 920, "add"),
    W("Contraction", 310, "subtract", false),
    W("Churn", 540, "subtract", false),
    W("Ending ARR", 9910, "result"),
  ]}
  scenario="AC"
  width={CARD_W}
  height={220}
  format={fK}
/>;

Net revenue retention

Vector Software · % · AC vs PY

NRR
114%+6+5.6%vs PY
Gross retention
92%+2+2.2%vs PY
Logo retention
88%-3-3.3%vs PY
import { KpiCard } from "ibcs-react"; // KpiStrip is a small local wrapper around KpiCard

<KpiStrip
  items={[
    {
      label: "NRR",
      values: { AC: 114, PY: 108 },
      comparisons: ["PY"],
      format: { ...fN, suffix: "%" },
    },
    {
      label: "Gross retention",
      values: { AC: 92, PY: 90 },
      comparisons: ["PY"],
      format: { ...fN, suffix: "%" },
    },
    {
      label: "Logo retention",
      values: { AC: 88, PY: 91 },
      comparisons: ["PY"],
      format: { ...fN, suffix: "%" },
    },
  ]}
/>;

Monthly churn rate

Vector Software · % · lower is better

PY 3.45AC 3JanFebMarAprMayJunJulAug-0.4-0.15-0.5-0.25-0.6-0.35-0.7-0.45
Line chart of 2 series - data table
ACPYΔPYΔPY%
Jan3.43.8-0.4-10.5%
Feb3.63.75-0.15-4.0%
Mar3.23.7-0.5-13.5%
Apr3.43.65-0.25-6.8%
May33.6-0.6-16.7%
Jun3.23.55-0.35-9.9%
Jul2.83.5-0.7-20.0%
Aug33.45-0.45-13.0%
import { LineChart } from "ibcs-react";

<LineChart
  data={["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug"].map((m, i) =>
    L(m, { AC: 3.4 - i * 0.1 + (i % 2 ? 0.3 : 0), PY: 3.8 - i * 0.05 }),
  )}
  comparison="PY"
  higherIsBetter={false}
  variance="abs"
  width={CARD_W}
  height={236}
  format={fN1}
/>;

Cohort retention

Vector Software · % retained by month (matrix)

 M0M1M2M3M4M5
ACACACACACAC
+Jan cohort1008271645955
+Feb cohort10085746661
+Mar cohort100796860
+Apr cohort1008877
+May cohort10084
import { MatrixTable } from "ibcs-react";

<MatrixTable
  rows={cohortRows}
  columns={cohortCols}
  values={cohortValues}
  scenarios={["AC"]}
  showVariance={false}
  labelWidth={92}
  format={fN}
/>;

DAU & stickiness

Vector Software · k users / DAU-MAU %

DAU (k)Stickiness %01020304050010203042Mon48Tue51Wed49Thu46Fri28Sat24Sun31353736332018
Combination chart data table
ACPYStickiness %
Mon42n/a31
Tue48n/a35
Wed51n/a37
Thu49n/a36
Fri46n/a33
Sat28n/a20
Sun24n/a18
import { ComboChart } from "ibcs-react";

<ComboChart
  data={[
    C("Mon", 42),
    C("Tue", 48),
    C("Wed", 51),
    C("Thu", 49),
    C("Fri", 46),
    C("Sat", 28),
    C("Sun", 24),
  ]}
  secondary={[
    { category: "Mon", value: 31 },
    { category: "Tue", value: 35 },
    { category: "Wed", value: 37 },
    { category: "Thu", value: 36 },
    { category: "Fri", value: 33 },
    { category: "Sat", value: 20 },
    { category: "Sun", value: 18 },
  ]}
  primaryLabel="DAU (k)"
  secondaryLabel="Stickiness %"
  secondaryFormat={fN}
  width={CARD_W}
  height={220}
  format={fN}
/>;

NPS trend

Vector Software · score · quarterly (with PY)

38Q142Q245Q351Q4+7+7+1+5
AC versus PY - data table
ACPYΔPYΔPY%
Q13831+7+22.6%
Q24235+7+20.0%
Q34544+1+2.3%
Q45146+5+10.9%
import { VarianceColumnChart } from "ibcs-react";

<VarianceColumnChart
  data={[C("Q1", 38, 31), C("Q2", 42, 35), C("Q3", 45, 44), C("Q4", 51, 46)]}
  comparison="PY"
  width={CARD_W}
  height={210}
  format={fN}
/>;

Feature adoption

Vector Software · % of accounts using feature

Dashboards86+633%Automations61+1324%API access44+517%Mobile app38-315%Single sign-on29+1111%Total258+32100%
Composition versus PY - data table
ValuePYΔPYShare
Dashboards8680+633%
Automations6148+1324%
API access4439+517%
Mobile app3841-315%
Single sign-on2918+1111%
Total258226+32100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Dashboards", 86, 80),
    S("Automations", 61, 48),
    S("API access", 44, 39),
    S("Mobile app", 38, 41),
    S("Single sign-on", 29, 18),
  ]}
  comparison="PY"
  width={CARD_W}
  height={220}
  labelWidth={120}
  format={fN}
/>;

Active users by plan

Vector Software · k · plan mix over time

124Q1138Q2152Q3168Q4EnterpriseProFree
Stacked columns - data table
FreeProEnterpriseTotal
Q184319124
Q2913611138
Q3964214152
Q41024917168
import { StackedChart } from "ibcs-react";

<StackedChart
  data={[
    { category: "Q1", values: { free: 84, pro: 31, ent: 9 } },
    { category: "Q2", values: { free: 91, pro: 36, ent: 11 } },
    { category: "Q3", values: { free: 96, pro: 42, ent: 14 } },
    { category: "Q4", values: { free: 102, pro: 49, ent: 17 } },
  ]}
  series={[
    { key: "free", label: "Free" },
    { key: "pro", label: "Pro" },
    { key: "ent", label: "Enterprise" },
  ]}
  orientation="column"
  width={CARD_W}
  height={210}
  format={fN}
  highlight="ent"
/>;

Expansion vs contraction

Vector Software · € k · net by month

120Jan140Feb-40Mar180Apr210May95Jun+30+30-100+50+50-45
AC versus PY - data table
ACPYΔPYΔPY%
Jan12090+30+33.3%
Feb140110+30+27.3%
Mar-4060-100-166.7%
Apr180130+50+38.5%
May210160+50+31.3%
Jun95140-45-32.1%
import { VarianceColumnChart } from "ibcs-react";

<VarianceColumnChart
  data={[
    C("Jan", 120, 90),
    C("Feb", 140, 110),
    C("Mar", -40, 60),
    C("Apr", 180, 130),
    C("May", 210, 160),
    C("Jun", 95, 140),
  ]}
  comparison="PY"
  width={CARD_W}
  height={210}
  format={fK}
/>;

Trial conversion funnel

Vector Software · count · signup → paid

Signups3.2K43%Activated2K26%Used core feat…1.2K17%Invited team6809%Converted to p…4105%Total7.5K100%
Composition versus PY - data table
ValuePYShare
Signups3.2Kn/a43%
Activated2Kn/a26%
Used core feature1.2Kn/a17%
Invited team680n/a9%
Converted to paid410n/a5%
Total7.5Kn/a100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Signups", 3200),
    S("Activated", 1980),
    S("Used core feature", 1240),
    S("Invited team", 680),
    S("Converted to paid", 410),
  ]}
  comparison="PY"
  showComparison={false}
  variance="none"
  width={CARD_W}
  height={210}
  labelWidth={120}
  format={fK}
/>;

Support volume & CSAT

Vector Software · tickets / CSAT %

TicketsCSAT %0100200300400020406080320W1290W2410W3380W4350W5300W6919387899294
Combination chart data table
ACPYCSAT %
W1320n/a91
W2290n/a93
W3410n/a87
W4380n/a89
W5350n/a92
W6300n/a94
import { ComboChart } from "ibcs-react";

<ComboChart
  data={[C("W1", 320), C("W2", 290), C("W3", 410), C("W4", 380), C("W5", 350), C("W6", 300)]}
  secondary={[
    { category: "W1", value: 91 },
    { category: "W2", value: 93 },
    { category: "W3", value: 87 },
    { category: "W4", value: 89 },
    { category: "W5", value: 92 },
    { category: "W6", value: 94 },
  ]}
  primaryLabel="Tickets"
  secondaryLabel="CSAT %"
  secondaryFormat={fN}
  width={CARD_W}
  height={220}
  format={fN}
/>;

Time-to-value vs account size

Vector Software · onboarded accounts

05101520020406080Days to valueHealth scoreMeridianBrightl…Tide…640160ARREnterpriseMidSMB
Bubble chart data table
Days to valueHealth scoreARRGroup
Brightline1288420Enterprise
Tideway576120Mid
Meridian2191640Enterprise
Item 436460SMB
Item 5980210Mid
Item 625845SMB
import { BubbleChart } from "ibcs-react";

<BubbleChart
  data={[
    { x: 12, y: 88, size: 420, group: "Enterprise", label: "Brightline" },
    { x: 5, y: 76, size: 120, group: "Mid", label: "Tideway" },
    { x: 21, y: 91, size: 640, group: "Enterprise", label: "Meridian" },
    { x: 3, y: 64, size: 60, group: "SMB" },
    { x: 9, y: 80, size: 210, group: "Mid" },
    { x: 2, y: 58, size: 45, group: "SMB" },
  ]}
  xLabel="Days to value"
  yLabel="Health score"
  sizeLabel="ARR"
  width={CARD_W}
  height={220}
  format={fN}
/>;

ARPU by segment

Vector Software · € / month · AC vs PY

Enterprise1,240+12070%Mid-market410+3023%SMB96+85%Self-serve29-22%Total1,775+156100%
Composition versus PY - data table
ValuePYΔPYShare
Enterprise1,2401,120+12070%
Mid-market410380+3023%
SMB9688+85%
Self-serve2931-22%
Total1,7751,619+156100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Enterprise", 1240, 1120),
    S("Mid-market", 410, 380),
    S("SMB", 96, 88),
    S("Self-serve", 29, 31),
  ]}
  comparison="PY"
  width={CARD_W}
  height={200}
  labelWidth={120}
  format={fN}
/>;

Operations & supply chain

Inventory, service levels, capacity, supplier risk and quality. 13 recipes.

Components used here: AreaChart, BubbleChart, DataTable, KpiCard, LineChart, MiniVarianceMultiples, StructureChart, TrendChart, VarianceColumnChart, WaterfallChart.

Inventory by warehouse

Northwind Materials · € m · AC vs PY

Rotterdam DC4+033%Hamburg DC3-024%Lyon DC3+020%Madrid DC2+015%Gdańsk DC1+09%Total13+1100%
Composition versus PY - data table
ValuePYΔPYShare
Rotterdam DC44+033%
Hamburg DC33-024%
Lyon DC32+020%
Madrid DC22+015%
Gdańsk DC11+09%
Total1312+1100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Rotterdam DC", 4.2, 3.8, undefined, false),
    S("Hamburg DC", 3.1, 3.4, undefined, false),
    S("Lyon DC", 2.6, 2.2, undefined, false),
    S("Madrid DC", 1.9, 1.7, undefined, false),
    S("Gdańsk DC", 1.1, 0.9, undefined, false),
  ]}
  comparison="PY"
  higherIsBetter={false}
  width={CARD_W}
  height={220}
  labelWidth={120}
  format={fM}
/>;

OTIF performance

Northwind Materials · % · AC vs target (PL=95)

92Jan94Feb91Mar96Apr97May95Jun-3-1-4+1+20
AC versus PL - data table
ACPLΔPLΔPL%
Jan9295-3-3.2%
Feb9495-1-1.1%
Mar9195-4-4.2%
Apr9695+1+1.1%
May9795+2+2.1%
Jun959500.0%
import { VarianceColumnChart } from "ibcs-react";

<VarianceColumnChart
  data={[
    C("Jan", 92, undefined, 95),
    C("Feb", 94, undefined, 95),
    C("Mar", 91, undefined, 95),
    C("Apr", 96, undefined, 95),
    C("May", 97, undefined, 95),
    C("Jun", 95, undefined, 95),
  ]}
  comparison="PL"
  width={CARD_W}
  height={210}
  format={fN}
/>;

Capacity utilization

Cobalt Devices · % · 13 periods, AC vs PL

ACPYPL74798477828780859083P1P2P3P4P5P6P7P8P9P10-6-1+4-3+2+70+5+10+3
Trend versus PL - data table
CurrentPYPLΔPLΔPL%
P174n/a80-6-7.5%
P279n/a80-1-1.3%
P384n/a80+4+5.0%
P477n/a80-3-3.8%
P582n/a80+2+2.5%
P687n/a80+7+8.8%
P780n/a8000.0%
P885n/a80+5+6.3%
P990n/a80+10+12.5%
P1083n/a80+3+3.8%
import { TrendChart } from "ibcs-react";

<TrendChart
  data={["P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10"].map((p, i) =>
    L(p, { AC: 74 + (i % 3) * 4 + i, PL: 80 }),
  )}
  comparison="PL"
  width={CARD_W}
  height={236}
  format={fN}
/>;

Demand vs production

Cobalt Devices · k units · plan vs actual

AC 59PL 57JanFebMarAprMayJun-4+2-4+2-4+2
Line chart of 2 series - data table
ACPLΔPLΔPL%
Jan3842-4-9.5%
Feb4745+2+4.4%
Mar4448-4-8.3%
Apr5351+2+3.9%
May5054-4-7.4%
Jun5957+2+3.5%
import { LineChart } from "ibcs-react";

<LineChart
  data={["Jan", "Feb", "Mar", "Apr", "May", "Jun"].map((m, i) =>
    L(m, { AC: 40 + i * 3 + (i % 2 ? 4 : -2), PL: 42 + i * 3 }),
  )}
  comparison="PL"
  higherIsBetter
  variance="abs"
  width={CARD_W}
  height={236}
  format={fN}
/>;

Supplier risk map

Northwind Materials · spend vs risk score

0204060800204060Annual spend (€ m)Risk scoreApex Res…Forge Me…Volt Ce…Cedar…410102.5VolumeCriticalStandardWatch
Bubble chart data table
Annual spend (€ m)Risk scoreVolumeGroup
Forge Metals1872340Critical
Cedar Pkg6431180Standard
Volt Cells4158260Watch
Item 4122290Standard
Apex Resin8048410Watch
Item 6301470Standard
import { BubbleChart } from "ibcs-react";

<BubbleChart
  data={[
    { x: 18, y: 72, size: 340, group: "Critical", label: "Forge Metals" },
    { x: 64, y: 31, size: 180, group: "Standard", label: "Cedar Pkg" },
    { x: 41, y: 58, size: 260, group: "Watch", label: "Volt Cells" },
    { x: 12, y: 22, size: 90, group: "Standard" },
    { x: 80, y: 48, size: 410, group: "Watch", label: "Apex Resin" },
    { x: 30, y: 14, size: 70, group: "Standard" },
  ]}
  xLabel="Annual spend (€ m)"
  yLabel="Risk score"
  sizeLabel="Volume"
  width={CARD_W}
  height={220}
  format={fN}
/>;

Inventory & service KPIs

Northwind Materials · AC vs PY

Inventory turns
×6.8+0.9+15.3%vs PY
Stockout rate
2.1%-1.3-38.2%vs PY
Fill rate
97%+2+2.1%vs PY
import { KpiCard } from "ibcs-react"; // KpiStrip is a small local wrapper around KpiCard

<KpiStrip
  items={[
    {
      label: "Inventory turns",
      values: { AC: 6.8, PY: 5.9 },
      comparisons: ["PY"],
      format: { ...fN1, currency: "×" },
    },
    {
      label: "Stockout rate",
      values: { AC: 2.1, PY: 3.4 },
      comparisons: ["PY"],
      higherIsBetter: false,
      format: { ...fN1, suffix: "%" },
    },
    {
      label: "Fill rate",
      values: { AC: 97, PY: 95 },
      comparisons: ["PY"],
      format: { ...fN, suffix: "%" },
    },
  ]}
/>;

On-time delivery trend

Northwind Materials · % · weekly, AC vs PY

AC 90PY 88.5W1W2W3W4W5W6W7W8
Area chart of AC - data table
ACPY
W18885
W29085.5
W39286
W48886.5
W59087
W69287.5
W78888
W89088.5
import { AreaChart } from "ibcs-react";

<AreaChart
  data={["W1", "W2", "W3", "W4", "W5", "W6", "W7", "W8"].map((w, i) =>
    L(w, { AC: 88 + (i % 3) * 2, PY: 85 + i * 0.5 }),
  )}
  scenario="AC"
  baseline="PY"
  width={CARD_W}
  height={210}
  format={fN}
/>;

Defect rate (PPM)

Cobalt Devices · ppm · lower is better

PY 760AC 600JanFebMarAprMayJunJulAug
Line chart of 2 series - data table
ACPY
Jan820900
Feb840880
Mar740860
Apr760840
May660820
Jun680800
Jul580780
Aug600760
import { LineChart } from "ibcs-react";

<LineChart
  data={["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug"].map((m, i) =>
    L(m, { AC: 820 - i * 40 + (i % 2 ? 60 : 0), PY: 900 - i * 20 }),
  )}
  comparison="PY"
  higherIsBetter={false}
  width={CARD_W}
  height={210}
  format={fN}
/>;

Order backlog

Cobalt Devices · € m · monthly with PY

AC 17PY 16JanFebMarAprMayJun
Area chart of AC - data table
ACPY
Jan1211
Feb1312
Mar1513
Apr1614
May1615
Jun1716
import { AreaChart } from "ibcs-react";

<AreaChart
  data={["Jan", "Feb", "Mar", "Apr", "May", "Jun"].map((m, i) =>
    L(m, { AC: 12 + i * 1.4 - (i > 3 ? 2 : 0), PY: 11 + i }),
  )}
  scenario="AC"
  baseline="PY"
  width={CARD_W}
  height={210}
  format={fK}
/>;

Lead time by supplier

Northwind Materials · days · AC vs PY

 
Volt Cells
42
+4+10.5
Forge Metals
28
+4+16.7
Apex Resin
19
-2-9.5
Cedar Packaging
14
-2-12.5
import { DataTable } from "ibcs-react";

<DataTable
  columns={varCols("lt", "Lead days", false)}
  rows={[
    { id: "s1", label: "Forge Metals", values: { lt: { AC: 28, PY: 24 } } },
    { id: "s2", label: "Cedar Packaging", values: { lt: { AC: 14, PY: 16 } } },
    { id: "s3", label: "Volt Cells", values: { lt: { AC: 42, PY: 38 } } },
    { id: "s4", label: "Apex Resin", values: { lt: { AC: 19, PY: 21 } } },
  ]}
  format={fN}
  defaultSort={{ key: "lt", dir: "desc" }}
/>;

Production yield - small multiples

Cobalt Devices · % · AC vs PY by line

Line A+2Q1+2Q2+2Q3
Line B-2Q1-2Q2+1Q3
Line C+2Q10Q2+1Q3
Line D-4Q1-2Q20Q3
Variance versus PY - data table
ACPYΔPY
Line A - Q19492+2
Line A - Q29593+2
Line A - Q39694+2
Line B - Q18890-2
Line B - Q28991-2
Line B - Q39190+1
Line C - Q19795+2
Line C - Q296960
Line C - Q39897+1
Line D - Q18286-4
Line D - Q28587-2
Line D - Q388880
import { MiniVarianceMultiples } from "ibcs-react";

<div style={{ width: CARD_W }}>
  <MiniVarianceMultiples
    groups={[
      { label: "Line A", data: [C("Q1", 94, 92), C("Q2", 95, 93), C("Q3", 96, 94)] },
      { label: "Line B", data: [C("Q1", 88, 90), C("Q2", 89, 91), C("Q3", 91, 90)] },
      { label: "Line C", data: [C("Q1", 97, 95), C("Q2", 96, 96), C("Q3", 98, 97)] },
      { label: "Line D", data: [C("Q1", 82, 86), C("Q2", 85, 87), C("Q3", 88, 88)] },
    ]}
    comparison="PY"
    columns={2}
    format={fN}
  />
</div>;

Freight cost bridge

Northwind Materials · € k · PY → AC

0+180+140-90-110120PY frei…VolumeFuel surc…Mode shiftRate rene…AC freight
Bridge of actual contributions - data table
ContributionRunning total
PY freight00
Volume+180180
Fuel surcharge+140320
Mode shift-90230
Rate renegotiation-110120
AC freight120120
import { WaterfallChart } from "ibcs-react";

<WaterfallChart
  data={[
    W("PY freight", 1240, "result"),
    W("Volume", 180, "add", false),
    W("Fuel surcharge", 140, "add", false),
    W("Mode shift", 90, "subtract"),
    W("Rate renegotiation", 110, "subtract"),
    W("AC freight", 1360, "result"),
  ]}
  scenario="AC"
  width={CARD_W}
  height={220}
  format={fK}
/>;

Scrap & rework cost

Cobalt Devices · € k · PY → AC

0+90-120-60-90PY scrapNew SKUsYield gainAutomationAC scrap
Bridge of actual contributions - data table
ContributionRunning total
PY scrap00
New SKUs+9090
Yield gain-120-30
Automation-60-90
AC scrap-90-90
import { WaterfallChart } from "ibcs-react";

<WaterfallChart
  data={[
    W("PY scrap", 410, "result"),
    W("New SKUs", 90, "add", false),
    W("Yield gain", 120, "subtract"),
    W("Automation", 60, "subtract"),
    W("AC scrap", 320, "result"),
  ]}
  scenario="AC"
  width={CARD_W}
  height={210}
  format={fK}
/>;

People & HR

Headcount, attrition, hiring, compensation and diversity. 13 recipes.

Components used here: BubbleChart, ComboChart, DataTable, KpiCard, LineChart, StackedChart, StructureChart, VarianceColumnChart.

Headcount by department

Aurora Retail · FTE · AC vs PY

Operations412+1445%Engineering168+2818%Sales134+1215%Customer success96+1511%Marketing54-66%G&A48+35%Total912+66100%
Composition versus PY - data table
ValuePYΔPYShare
Operations412398+1445%
Engineering168140+2818%
Sales134122+1215%
Customer success9681+1511%
Marketing5460-66%
G&A4845+35%
Total912846+66100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Operations", 412, 398),
    S("Engineering", 168, 140),
    S("Sales", 134, 122),
    S("Customer success", 96, 81),
    S("Marketing", 54, 60),
    S("G&A", 48, 45),
  ]}
  comparison="PY"
  width={CARD_W}
  height={230}
  labelWidth={130}
  format={fN}
/>;

Attrition trend

Aurora Retail · % annualized · lower better

PY 14.6AC 12.9JanFebMarAprMayJunJulAug-2-1.1-2.2-1.3-2.4-1.5-2.6-1.7
Line chart of 2 series - data table
ACPYΔPYΔPY%
Jan1416-2-12.5%
Feb14.715.8-1.1-7.0%
Mar13.415.6-2.2-14.1%
Apr14.115.4-1.3-8.4%
May12.815.2-2.4-15.8%
Jun13.515-1.5-10.0%
Jul12.214.8-2.6-17.6%
Aug12.914.6-1.7-11.6%
import { LineChart } from "ibcs-react";

<LineChart
  data={["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug"].map((m, i) =>
    L(m, { AC: 14 - i * 0.3 + (i % 2 ? 1 : 0), PY: 16 - i * 0.2 }),
  )}
  comparison="PY"
  higherIsBetter={false}
  variance="abs"
  width={CARD_W}
  height={236}
  format={fN1}
/>;

Hiring funnel

Aurora Retail · count · application → hire

Applications2.8K73%Phone screen64017%Onsite2206%Offer962%Hired712%Total3.9K100%
Composition versus PY - data table
ValuePYShare
Applications2.8Kn/a73%
Phone screen640n/a17%
Onsite220n/a6%
Offer96n/a2%
Hired71n/a2%
Total3.9Kn/a100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Applications", 2840),
    S("Phone screen", 640),
    S("Onsite", 220),
    S("Offer", 96),
    S("Hired", 71),
  ]}
  comparison="PY"
  showComparison={false}
  variance="none"
  width={CARD_W}
  height={210}
  labelWidth={104}
  format={fK}
/>;

Compensation by level

Aurora Retail · € k · base salary spread

0123456050100150LevelMedian base (€ k)L2L1L3M1M2D124060HeadcountICManagerDirector
Bubble chart data table
LevelMedian base (€ k)HeadcountGroup
L1142180IC
L2258240IC
L3378160IC
M1410290Manager
M2513850Manager
D1619022Director
import { BubbleChart } from "ibcs-react";

<BubbleChart
  data={[
    { x: 1, y: 42, size: 180, group: "IC", label: "L1" },
    { x: 2, y: 58, size: 240, group: "IC", label: "L2" },
    { x: 3, y: 78, size: 160, group: "IC", label: "L3" },
    { x: 4, y: 102, size: 90, group: "Manager", label: "M1" },
    { x: 5, y: 138, size: 50, group: "Manager", label: "M2" },
    { x: 6, y: 190, size: 22, group: "Director", label: "D1" },
  ]}
  xLabel="Level"
  yLabel="Median base (€ k)"
  sizeLabel="Headcount"
  width={CARD_W}
  height={220}
  format={fN}
/>;

Gender diversity by org

Aurora Retail · % · current

Engineering100Sales100Operations100Leadership100WomenMenOther…
Stacked bars - data table
WomenMenOther / N/ATotal
Engineering32644100
Sales48493100
Operations41563100
Leadership38602100
import { StackedChart } from "ibcs-react";

<StackedChart
  data={[
    { category: "Engineering", values: { w: 32, m: 64, o: 4 } },
    { category: "Sales", values: { w: 48, m: 49, o: 3 } },
    { category: "Operations", values: { w: 41, m: 56, o: 3 } },
    { category: "Leadership", values: { w: 38, m: 60, o: 2 } },
  ]}
  series={[
    { key: "w", label: "Women" },
    { key: "m", label: "Men" },
    { key: "o", label: "Other / N/A" },
  ]}
  orientation="bar"
  width={CARD_W}
  height={210}
  format={fN}
/>;

Headcount plan vs actual

Aurora Retail · FTE · AC vs PL by quarter

920Q1968Q21KQ31KQ4-20-12+5-12
AC versus PL - data table
ACPLΔPLΔPL%
Q1920940-20-2.1%
Q2968980-12-1.2%
Q31K1K+5+0.5%
Q41K1.1K-12-1.1%
import { VarianceColumnChart } from "ibcs-react";

<VarianceColumnChart
  data={[
    C("Q1", 920, undefined, 940),
    C("Q2", 968, undefined, 980),
    C("Q3", 1010, undefined, 1005),
    C("Q4", 1048, undefined, 1060),
  ]}
  comparison="PL"
  width={CARD_W}
  height={210}
  format={fK}
/>;

Tenure distribution

Aurora Retail · FTE · by band

All staff1.1K<1 yr1-3 yr3-5 yr5+ yr
Stacked bars - data table
<1 yr1-3 yr3-5 yr5+ yrTotal
All staff2403802901801.1K
import { StackedChart } from "ibcs-react";

<StackedChart
  data={[{ category: "All staff", values: { y0: 240, y1: 380, y3: 290, y5: 180 } }]}
  series={[
    { key: "y0", label: "<1 yr" },
    { key: "y1", label: "1-3 yr" },
    { key: "y3", label: "3-5 yr" },
    { key: "y5", label: "5+ yr" },
  ]}
  orientation="bar"
  width={CARD_W}
  height={150}
  format={fK}
  showTotals
/>;

Talent KPIs

Aurora Retail · AC vs PY

Time to hire
32 d-9-22.0%vs PY
Offer accept
84%+5+6.3%vs PY
eNPS
28+9+47.4%vs PY
import { KpiCard } from "ibcs-react"; // KpiStrip is a small local wrapper around KpiCard

<KpiStrip
  items={[
    {
      label: "Time to hire",
      values: { AC: 32, PY: 41 },
      comparisons: ["PY"],
      higherIsBetter: false,
      format: { ...fN, suffix: " d" },
    },
    {
      label: "Offer accept",
      values: { AC: 84, PY: 79 },
      comparisons: ["PY"],
      format: { ...fN, suffix: "%" },
    },
    { label: "eNPS", values: { AC: 28, PY: 19 }, comparisons: ["PY"], format: fN },
  ]}
/>;

Span of control

Aurora Retail · reports per manager · by org

 
Support
11
+0.8+7.8
Operations
9.2
+0.8+9.5
Sales
7.4
-0.5-6.3
Engineering
6.1
+0.3+5.2
import { DataTable } from "ibcs-react";

<DataTable
  columns={varCols("span", "Avg span")}
  rows={[
    { id: "o1", label: "Operations", values: { span: { AC: 9.2, PY: 8.4 } } },
    { id: "o2", label: "Engineering", values: { span: { AC: 6.1, PY: 5.8 } } },
    { id: "o3", label: "Sales", values: { span: { AC: 7.4, PY: 7.9 } } },
    { id: "o4", label: "Support", values: { span: { AC: 11.0, PY: 10.2 } } },
  ]}
  format={fN1}
  defaultSort={{ key: "span", dir: "desc" }}
/>;

Offer acceptance rate

Aurora Retail · % · monthly AC vs PY

AC 86PY 80JanFebMarAprMayJun
Line chart of 2 series - data table
ACPY
Jan7875
Feb8276
Mar8077
Apr8478
May8279
Jun8680
import { LineChart } from "ibcs-react";

<LineChart
  data={["Jan", "Feb", "Mar", "Apr", "May", "Jun"].map((m, i) =>
    L(m, { AC: 78 + i + (i % 2 ? 3 : 0), PY: 75 + i }),
  )}
  comparison="PY"
  width={CARD_W}
  height={200}
  format={fN}
/>;

Training hours per FTE

Aurora Retail · hours · AC vs PL target

28Eng16Sales12Ops22Support+4-4-2+4
AC versus PL - data table
ACPLΔPLΔPL%
Eng2824+4+16.7%
Sales1620-4-20.0%
Ops1214-2-14.3%
Support2218+4+22.2%
import { VarianceColumnChart } from "ibcs-react";

<VarianceColumnChart
  data={[
    C("Eng", 28, undefined, 24),
    C("Sales", 16, undefined, 20),
    C("Ops", 12, undefined, 14),
    C("Support", 22, undefined, 18),
  ]}
  comparison="PL"
  width={CARD_W}
  height={210}
  format={fN}
/>;

Workforce cost & FTE

Aurora Retail · € m / FTE · combo

Cost (€ m)FTE020406002004006008001K58FY2364FY2471FY2578FY269109901K
Combination chart data table
ACPYFTE
FY2358n/a840
FY2464n/a910
FY2571n/a990
FY2678n/a1K
import { ComboChart } from "ibcs-react";

<ComboChart
  data={[C("FY23", 58), C("FY24", 64), C("FY25", 71), C("FY26", 78)]}
  secondary={[
    { category: "FY23", value: 840 },
    { category: "FY24", value: 910 },
    { category: "FY25", value: 990 },
    { category: "FY26", value: 1048 },
  ]}
  primaryLabel="Cost (€ m)"
  secondaryLabel="FTE"
  secondaryFormat={fK}
  width={CARD_W}
  height={220}
  format={fK}
/>;

Absenteeism rate

Aurora Retail · % · monthly, lower better

PY 3.4AC 2.9JanFebMarAprMayJunJulAug
Line chart of 2 series - data table
ACPY
Jan3.93.4
Feb2.93.4
Mar2.93.4
Apr3.93.4
May2.93.4
Jun2.93.4
Jul3.93.4
Aug2.93.4
import { LineChart } from "ibcs-react";

<LineChart
  data={["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug"].map((m, i) =>
    L(m, { AC: 3.1 + (i % 3 === 0 ? 0.8 : -0.2), PY: 3.4 }),
  )}
  comparison="PY"
  higherIsBetter={false}
  width={CARD_W}
  height={200}
  format={fN1}
/>;

Executive & KPI scorecards

Roll-ups for the board pack: scorecards, profit walks, regional multiples and a balanced scorecard. 12 recipes.

Components used here: AreaChart, ComparisonTable, DataTable, KpiCard, MatrixTable, MiniVarianceMultiples, Sparkline, StructureChart, TrendChart, WaterfallChart.

Company scorecard

Northwind Materials · group KPIs · AC vs PY

Revenue
30.1M+4.5M+17.6%vs PY
Op. margin
34.6%+4.5+15.0%vs PY
Net income
8.9M+800K+9.9%vs PY
FCF
6.2M+1.4M+29.2%vs PY
import { KpiCard } from "ibcs-react"; // KpiStrip is a small local wrapper around KpiCard

<KpiStrip
  items={[
    { label: "Revenue", values: { AC: 30.1e6, PY: 25.6e6 }, comparisons: ["PY"], format: fM },
    {
      label: "Op. margin",
      values: { AC: 34.6, PY: 30.1 },
      comparisons: ["PY"],
      format: { ...fN1, suffix: "%" },
    },
    { label: "Net income", values: { AC: 8.9e6, PY: 8.1e6 }, comparisons: ["PY"], format: fM },
    { label: "FCF", values: { AC: 6.2e6, PY: 4.8e6 }, comparisons: ["PY"], format: fM },
  ]}
/>;

Revenue vs plan

Group · € m · 13 periods, AC + FC vs PL

ACPYPL2.3M2.4M2.6M2.5M2.6M2.7M2.7M2.8M2.9M3M3.1M3.1M3.2MP1P2P3P4P5P6P7P8P9P10P11P12P13+2.2%+3.0%+2.8%-0.8%+2.7%+3.4%-0.7%+2.2%+2.8%+2.4%+1.7%+1.3%+1.6%
Trend versus PL - data table
CurrentPYPLΔPLΔPL%
P12.3M2.2M2.3M+50K+2.2%
P22.4M2.2M2.4M+70K+3.0%
P32.6M2.4M2.5M+70K+2.8%
P42.5M2.4M2.5M-20K-0.8%
P52.6M2.5M2.6M+70K+2.7%
P62.7M2.5M2.6M+90K+3.4%
P72.7M2.6M2.7M-20K-0.7%
P82.8M2.6M2.7M+60K+2.2%
P92.9M2.7M2.9M+80K+2.8%
P10 (FC)3M2.8M2.9M+70K+2.4%
P11 (FC)3.1M2.9M3M+50K+1.7%
P12 (FC)3.1M3M3.1M+40K+1.3%
P13 (FC)3.2M3M3.2M+50K+1.6%
import { TrendChart } from "ibcs-react";

<TrendChart
  data={sampleMonthlyTrend}
  comparison="PL"
  variance="pct"
  width={CARD_W}
  height={236}
  format={fK}
/>;

Profit waterfall

Group · € m · revenue → net income

+30-10-10-29RevenueCOGSOpexTaxNet income
Bridge of actual contributions - data table
ContributionRunning total
Revenue+3030
COGS-1020
Opex-1010
Tax-29
Net income99
import { WaterfallChart } from "ibcs-react";

<WaterfallChart
  data={[
    W("Revenue", 30.1, "add"),
    W("COGS", 9.7, "subtract", false),
    W("Opex", 10.0, "subtract", false),
    W("Tax", 1.8, "subtract", false),
    W("Net income", 8.6, "result"),
  ]}
  scenario="AC"
  width={CARD_W}
  height={220}
  format={fM}
/>;

Regional performance

Group · € m · AC vs PY (small multiples)

Americas+1Q1+1Q2+1Q3+1Q4
EMEA+0Q1+1Q2+0Q3+1Q4
APAC+1Q1+1Q2+1Q3+1Q4
Other-0Q1-0Q2+0Q3-0Q4
Variance versus PY - data table
ACPYΔPY
Americas - Q188+1
Americas - Q298+1
Americas - Q399+1
Americas - Q4109+1
EMEA - Q166+0
EMEA - Q276+1
EMEA - Q376+0
EMEA - Q477+1
APAC - Q132+1
APAC - Q233+1
APAC - Q343+1
APAC - Q443+1
Other - Q111-0
Other - Q211-0
Other - Q311+0
Other - Q411-0
import { MiniVarianceMultiples } from "ibcs-react";

<div style={{ width: CARD_W }}>
  <MiniVarianceMultiples
    groups={[
      {
        label: "Americas",
        data: [C("Q1", 8.4, 7.9), C("Q2", 8.8, 8.1), C("Q3", 9.1, 8.6), C("Q4", 9.9, 9.0)],
      },
      {
        label: "EMEA",
        data: [C("Q1", 6.2, 5.8), C("Q2", 6.5, 6.0), C("Q3", 6.8, 6.4), C("Q4", 7.4, 6.9)],
      },
      {
        label: "APAC",
        data: [C("Q1", 3.1, 2.4), C("Q2", 3.4, 2.7), C("Q3", 3.7, 3.0), C("Q4", 4.2, 3.3)],
      },
      {
        label: "Other",
        data: [C("Q1", 1.1, 1.3), C("Q2", 1.0, 1.2), C("Q3", 1.2, 1.1), C("Q4", 0.9, 1.0)],
      },
    ]}
    comparison="PY"
    columns={2}
    format={fK}
  />
</div>;

Strategic initiatives

Group · status & impact · current quarter

 Trend
Margin recovery programme
72
4.2
ERP consolidation
41
1.8
DTC channel launch
88
6.1
import { DataTable } from "ibcs-react";

<DataTable
  columns={[
    { key: "prog", label: "Progress%", kind: "value", scenario: "AC" },
    { key: "impact", label: "€ m impact", kind: "value", scenario: "AC", format: fN1 },
    { key: "spk", label: "Trend", kind: "sparkline", measure: "spk" },
  ]}
  rows={[
    {
      id: "i1",
      label: "Margin recovery programme",
      values: { prog: { AC: 72 }, impact: { AC: 4.2 } },
      spark: { spk: [10, 20, 35, 50, 62, 72] },
    },
    {
      id: "i2",
      label: "ERP consolidation",
      values: { prog: { AC: 41 }, impact: { AC: 1.8 } },
      spark: { spk: [5, 12, 20, 28, 35, 41] },
    },
    {
      id: "i3",
      label: "DTC channel launch",
      values: { prog: { AC: 88 }, impact: { AC: 6.1 } },
      spark: { spk: [30, 48, 60, 71, 80, 88] },
    },
  ]}
  format={fN}
/>;

Market share

Group · % · AC vs PY by category

Core materials24+239%Specialty18+429%Recycled11+418%Coatings9-115%Total62+9100%
Composition versus PY - data table
ValuePYΔPYShare
Core materials2422+239%
Specialty1814+429%
Recycled117+418%
Coatings910-115%
Total6253+9100%
import { StructureChart } from "ibcs-react";

<StructureChart
  data={[
    S("Core materials", 24, 22),
    S("Specialty", 18, 14),
    S("Recycled", 11, 7),
    S("Coatings", 9, 10),
  ]}
  comparison="PY"
  width={CARD_W}
  height={210}
  labelWidth={120}
  format={fN}
/>;

Customer satisfaction

Group · CSAT · sparkline tiles

CSAT
92%
NPS
51
Complaints
1.2k
import { Sparkline } from "ibcs-react"; // SparkTile is a small local wrapper around Sparkline

<div style={{ display: "flex", gap: 16, flexWrap: "wrap" }}>
  <SparkTile label="CSAT" value="92%" data={[88, 89, 87, 90, 91, 92]} color="#3b6e8f" />
  <SparkTile label="NPS" value="51" data={[38, 42, 45, 44, 48, 51]} color="#5e8c22" />
  <SparkTile
    label="Complaints"
    value="1.2k"
    data={[1.8, 1.7, 1.6, 1.5, 1.3, 1.2]}
    color="#c0392b"
  />
</div>;

Cash position

Group · € m · 12-month area, AC vs PY

AC 6PY 6JanFebMarAprMayJunJulAugSepOctNovDec
Area chart of AC - data table
ACPY
Jan44
Feb54
Mar74
Apr74
May74
Jun75
Jul65
Aug55
Sep45
Oct55
Nov56
Dec66
import { AreaChart } from "ibcs-react";

<AreaChart
  data={["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"].map(
    (m, i) => L(m, { AC: 4 + Math.round(Math.sin(i / 2) * 2) + i * 0.3, PY: 3.5 + i * 0.2 }),
  )}
  scenario="AC"
  baseline="PY"
  width={CARD_W}
  height={210}
  format={fK}
/>;

Top & bottom movers

Group · € k · biggest ΔPY swings

 
Recycled line
4,100
+1,500+57.7
Specialty coatings
3,200
+800+33.3
Bulk resin
5,600
-500-8.2
Legacy adhesives
1,800
-1,100-37.9
import { DataTable } from "ibcs-react";

<DataTable
  columns={varCols("delta", "Revenue")}
  rows={[
    { id: "m1", label: "Recycled line", values: { delta: { AC: 4100, PY: 2600 } } },
    { id: "m2", label: "Specialty coatings", values: { delta: { AC: 3200, PY: 2400 } } },
    { id: "m3", label: "Legacy adhesives", values: { delta: { AC: 1800, PY: 2900 } } },
    { id: "m4", label: "Bulk resin", values: { delta: { AC: 5600, PY: 6100 } } },
  ]}
  format={fN}
  defaultSort={{ key: "delta_d", dir: "desc" }}
/>;

Balanced scorecard

Group · perspectives × quarters (AC vs PL)

 Q3Q4
PLACΔBdgPLACΔBdg
+Financial40.441.6+1.241.644.4+2.8
+Revenue7.47.6+0.27.68.4+0.8
+Margin %3334+13436+2
+Customer134137+3137143+6
+NPS4445+14651+5
+Retention %9092+29192+1
+Process9591-49596+1
+OTIF %9591-49596+1
import { MatrixTable } from "ibcs-react";

<MatrixTable
  rows={[
    {
      id: "fin",
      label: "Financial",
      emphasis: true,
      children: [
        { id: "rev", label: "Revenue" },
        { id: "mgn", label: "Margin %", higherIsBetter: true },
      ],
    },
    {
      id: "cust",
      label: "Customer",
      emphasis: true,
      children: [
        { id: "nps", label: "NPS" },
        { id: "ret", label: "Retention %" },
      ],
    },
    { id: "proc", label: "Process", emphasis: true, children: [{ id: "otif", label: "OTIF %" }] },
  ]}
  columns={[
    { id: "q3", label: "Q3" },
    { id: "q4", label: "Q4" },
  ]}
  values={{
    rev: { q3: { PL: 7.4, AC: 7.6 }, q4: { PL: 7.6, AC: 8.4 } },
    mgn: { q3: { PL: 33, AC: 34 }, q4: { PL: 34, AC: 36 } },
    nps: { q3: { PL: 44, AC: 45 }, q4: { PL: 46, AC: 51 } },
    ret: { q3: { PL: 90, AC: 92 }, q4: { PL: 91, AC: 92 } },
    otif: { q3: { PL: 95, AC: 91 }, q4: { PL: 95, AC: 96 } },
  }}
  scenarios={["PL", "AC"]}
  showVariance
  varianceScenarios={{ actual: "AC", base: "PL" }}
  labelWidth={120}
  format={fN}
/>;

ESG metrics

Group · sustainability KPIs · AC vs PY

CO₂ (kt)
142-26-15.5%vs PY
Renewable %
61%+13+27.1%vs PY
Recordables
7-5-41.7%vs PY
import { KpiCard } from "ibcs-react"; // KpiStrip is a small local wrapper around KpiCard

<KpiStrip
  items={[
    {
      label: "CO₂ (kt)",
      values: { AC: 142, PY: 168 },
      comparisons: ["PY"],
      higherIsBetter: false,
      format: fN,
    },
    {
      label: "Renewable %",
      values: { AC: 61, PY: 48 },
      comparisons: ["PY"],
      format: { ...fN, suffix: "%" },
    },
    {
      label: "Recordables",
      values: { AC: 7, PY: 12 },
      comparisons: ["PY"],
      higherIsBetter: false,
      format: fN,
    },
  ]}
/>;

Flanking comparison table

Electronic Inc. · kEUR · month vs YTD

Current monthYear to date
PYACΔPYΔPY% PYACΔPYΔPY%
560
558
-2-0Austria
5,078
5,509
+431+8
56
58
+2+4Belgium
531
484
-47-9
140
134
-6-4France
1,290
1,354
+64+5
345
260
-85-25Germany
3,124
2,850
-274-9
78
86
+8+10Poland
816
854
+38+5
77
86
+9+12Sweden
809
764
-45-6
61
66
+5+8Switzerland
604
678
+74+12
502
545
+43+9Other
5,602
5,441
-161-3
1,819
1,793
-26-1Europe
17,854
17,934
+80+0
119
121
+2+2Brazil
1,205
1,314
+109+9
65
59
-6-9Canada
629
718
+89+14
346
311
-35-10USA
3,406
3,239
-167-5
438
399
-39-9Other
4,166
4,008
-158-4
968
890
-78-8Americas
9,406
9,279
-127-1
54
62
+8+15Australia
517
588
+71+14
266
231
-35-13China
2,107
2,399
+292+14
9
11
+2+22Japan
67
144
+77+115
234
255
+21+9Other
2,351
2,145
-206-9
563
559
-4-1Rest of world
5,042
5,276
+234+5
3,350
3,242
-108-3World
32,302
32,489
+187+1
import { ComparisonTable } from "ibcs-react";

<div style={{ minWidth: 560 }}>
  <ComparisonTable
    rows={sampleTableRegions}
    leftColumns={tableT02Left}
    rightColumns={tableT02Right}
    leftGroupLabel="Current month"
    rightGroupLabel="Year to date"
    showTotals
    totalsLabel="World"
    format={fN}
  />
</div>;

About these examples

All companies - Northwind Materials, Aurora Retail, Vector Software, Lumen Media, Cobalt Devices, Helios Foods and the like - and every number in them are invented for illustration. Charts are sized to a single CARD_W budget so the recipes stay comparable; wide tables scroll inside their frame rather than bleeding across the page.

Want to try variations on your own numbers? The playground edits a live statement, and the report route shows a full page assembled from these building blocks.

ibcs-react is an independent open-source library and is not affiliated with, certified by, or endorsed by the IBCS Association or ISO. It follows the IBCS® notation rules (the basis of ISO 24896); IBCS® is a registered trademark of the IBCS Association.

On this page

Shared shorthandsFinance & accountingIncome statement (waterfall)Balance sheetCash flow bridgeP&L bridge - PY → AC operating incomeBudget vs actual - quarterly revenueRevenue variance analysisGross-margin walkOperating-expense breakdownWorking-capital metricsAR aging by segmentRevenue by regionEBITDA trendMulti-year P&L statementCost-centre varianceCapex vs depreciationFree cash flowReturn-on-assets driver treeInterest-coverage & leverageSalesRevenue by product lineRevenue by channelSales-rep leaderboardSales pipeline funnelWin rate by regionQuota attainment by teamBookings vs targetDiscount vs deal sizeNew vs existing businessAverage deal size trendTop accounts by revenueRegional bookings - small multiplesDiscount analysis by tierLost-deal reasonsMarketingMarketing funnelMQL → SQL conversionCAC by channelLTV : CAC & paybackChannel ROIWeb traffic trendCampaign performanceEmail engagementSpend & cost-per-leadChannel mix of MQLsBrand vs performance spendSEO vs paid sessionsLanding-page conversionProduct & SaaSMRR trendARR bridgeNet revenue retentionMonthly churn rateCohort retentionDAU & stickinessNPS trendFeature adoptionActive users by planExpansion vs contractionTrial conversion funnelSupport volume & CSATTime-to-value vs account sizeARPU by segmentOperations & supply chainInventory by warehouseOTIF performanceCapacity utilizationDemand vs productionSupplier risk mapInventory & service KPIsOn-time delivery trendDefect rate (PPM)Order backlogLead time by supplierProduction yield - small multiplesFreight cost bridgeScrap & rework costPeople & HRHeadcount by departmentAttrition trendHiring funnelCompensation by levelGender diversity by orgHeadcount plan vs actualTenure distributionTalent KPIsSpan of controlOffer acceptance rateTraining hours per FTEWorkforce cost & FTEAbsenteeism rateExecutive & KPI scorecardsCompany scorecardRevenue vs planProfit waterfallRegional performanceStrategic initiativesMarket shareCustomer satisfactionCash positionTop & bottom moversBalanced scorecardESG metricsFlanking comparison tableAbout these examples