ChartBullet
ChartBullet manifests describe IBCS bullet graphs: one horizontal row per
KPI with a solid actual bar and a target marker. The default mode applies
the IBCS improvements over the classic Stephen Few bullet graph —
normalized targets (every row is scaled to fractions of its target, so
one continuous target line spans all rows and KPIs become visually
comparable) and integrated variance bars between actual and target in
the IBCS variance colors. The classic look with per-row scales and
qualitative gray bands is opt-in.
Minimal definition
Section titled “Minimal definition”The smallest well-formed ChartBullet sets the required spec.dataset plus the
fields that give the chart a message: a chartTitle and the two compared
measures. Both measures auto-detect, but the detected target depends on which
scenarios the dataset carries, so pinning them keeps the comparison stable.
apiVersion: bino.bi/v1alpha1
kind: ChartBullet
metadata:
name: revenue_bullet
spec:
dataset: revenue_by_region
chartTitle: "Revenue vs. plan by region"
actual: ac1
target:
measure: pl1
label: "Plan"All attributes are listed in the Attribute Reference below.
actual and target accept either the bare slot shown above or the object form
(see Measure tokens), and the chart renders either normalized
(the default) or in the classic per-row style (see Data mapping).
Measure tokens
Section titled “Measure tokens”The actual and target mappings accept either a bare scenario slot
or an object whose measure property is a slot:
- Scenario slots:
ac1–ac4,pp1–pp4,fc1–fc4,pl1–pl4— the row columns of the dataset. - Variance tokens are not allowed — the bullet variance is implicit
(actual vs. target), so
dac1_pl1-style tokens have no meaning here.
A bare string is shorthand for the object form: actual: ac1 equals
actual: { measure: ac1 }.
Both measures auto-detect when omitted: actual prefers ac1 (else the
first available scenario), target prefers pl1, then pp1, then fc1.
A dataset without any target scenario renders plain actual bars with a
warning.
Data mapping
Section titled “Data mapping”One KPI row aggregates all dataset rows sharing the same level value
(plain SUM, so cost KPIs show positive magnitudes). Values are drawn as
delivered (no auto-SI scaling).
levelpicks the hierarchy column that identifies a KPI row (autouses the deepest populated level ofrowGroup→category→subCategory).normalize: target(the default) maps every row to fractions of its target: the target line aligns across rows at 100% and the rows become visually comparable. Rows whose target is missing or not positive cannot be normalized and render as label + value only, with a warning.normalize: nonedraws the classic bullet: absolute values on per-row scales with tick strips and per-row target ticks.- The favorable/unfavorable reading of a variance follows the row's
operationcolumn:"-"marks cost-type KPIs and inverts the sentiment (an actual below a cost target is favorable).
Fields
Section titled “Fields”dataset– required dataset name, inline definition, or an array of those.actual,target– optional measure mappings (slot or object withmeasure,label,unit); omitted values auto-detect.ranges– optional qualitative bands as ascending fractions of the target, one or two positive numbers (IBCS rejects a third band of arbitrary length); an empty array is rejected. Classic mode only; ignored with a warning whilenormalizeistarget.normalize–target(default) ornone.variances–auto(default; variance bars in normalized mode) ornone.level– KPI row level.order,orderDirection– row sorting; the sort key isauto, a hierarchy column (rowgroup,category,subcategory, or their…indexvariants) or a scenario slot; omitted uses the dataset's suggested order.limit– max KPI rows; truncates without a REST aggregate (summing heterogeneous KPIs would be meaningless).0means unlimited.labels– value labels:show(autoornone) anddecimals(0–4, default 1).filter– optional AlaSQL WHERE fragment.chartTitle– optional title.scale– proportional font scaling, same semantics as the other charts (none,auto, or a fixed factor); bullet charts auto-fit against the parent height.i18nNamespace– optional namespace consulted for this component's labels; missing keys fall back to_system. When unset, it is resolved from the nearest ancestor carrying one.selectedStyle– optional name of aComponentStyleto apply; merged over the_systemand_defaultstyles.ruleset– optional name of aRuleSetto apply, orinherited-closest/inherited-pageto inherit the surrounding layout's rule set. The target marker's treatment follows the target scenario's rule-set family (PL solid, FC dashed, PP gray).
Example: Minimal auto-detected bullet
Section titled “Example: Minimal auto-detected bullet”Everything auto-detects — actual ac1, target pl1 > pp1 > fc1,
level and order from the dataset:
---
apiVersion: bino.bi/v1alpha1
kind: ChartBullet
metadata:
name: kpi_overview
spec:
dataset: kpisExample: Explicit target with sorting
Section titled “Example: Explicit target with sorting”---
apiVersion: bino.bi/v1alpha1
kind: ChartBullet
metadata:
name: revenue_bullet
spec:
dataset: revenue_by_region
chartTitle: "Revenue vs. plan by region"
actual: ac1
target:
measure: pl1
label: "Plan"
order: ac1
orderDirection: descExample: Classic Stephen Few look
Section titled “Example: Classic Stephen Few look”Per-row scales, up to two gray bands, no variance bars:
---
apiVersion: bino.bi/v1alpha1
kind: ChartBullet
metadata:
name: revenue_bullet_classic
spec:
dataset: revenue_by_region
chartTitle: "Revenue vs. plan (classic bullet)"
actual: ac1
target: pl1
normalize: none
ranges: [0.6, 0.9]
variances: none
labels:
decimals: 0Attribute Reference
Section titled “Attribute Reference”Common Metadata
Section titled “Common Metadata”| Attribute | Type | Required | Default | Description |
|---|---|---|---|---|
apiVersion | string | yes | — | Must be bino.bi/v1alpha1. |
kind | string | yes | — | Must be ChartBullet. |
metadata.name | string | yes | — | Unique identifier. |
metadata.labels | object | no | — | Key-value pairs for categorization and constraint matching. |
metadata.annotations | object | no | — | Arbitrary key-value metadata, not used by the system. |
metadata.description | string | no | — | Free-form description. |
metadata.constraints | array | no | — | Conditional inclusion rules. See Constraints. |
Spec Attributes
Section titled “Spec Attributes”| Attribute | Type | Required | Default | Description | Sample |
|---|---|---|---|---|---|
spec.dataset | string, object, or array | yes | — | Dataset reference: a name, an inline DataSet definition, or an array of those (at least one). Maps to the datasets HTML attribute. | dataset: kpis |
spec.actual | string or object | no | auto (ac1, else the first available scenario) | Actual-value measure mapping: a bare scenario slot or the object form below. Maps to the actual HTML attribute. | actual: ac1 |
spec.actual.measure | string | yes (in object form) | — | Plain scenario slot: ac1–ac4, pp1–pp4, fc1–fc4, pl1–pl4. Variance tokens are not allowed. | measure: ac1 |
spec.actual.label | string | no | — | Caption of the measure, shown above the first row. | label: "AC" |
spec.actual.unit | string | no | — | Unit caption, rendered once as in EUR k in the chart header. Values are drawn as delivered — scale in the DataSet SQL. | unit: "EUR k" |
spec.target | string or object | no | auto (pl1 > pp1 > fc1) | Target measure mapping: a bare scenario slot or the object form below. Without any target scenario the chart renders actual bars only. Maps to the target HTML attribute. | target: { measure: pl1, label: "Plan" } |
spec.target.measure | string | yes (in object form) | — | Plain scenario slot: ac1–ac4, pp1–pp4, fc1–fc4, pl1–pl4. Variance tokens are not allowed. | measure: pl1 |
spec.target.label | string | no | — | Caption of the measure, shown at the target line. | label: "Plan" |
spec.target.unit | string | no | — | Unit caption, rendered once as in EUR k in the chart header. | unit: "EUR k" |
spec.ranges | array of numbers | no | — | One or two ascending fractions of the target, each greater than 0 (classic mode gray bands); an empty array is rejected. Maps to the ranges HTML attribute. | ranges: [0.6, 0.9] |
spec.ranges[] | number | — | — | A single band boundary as a fraction of the target, greater than 0. | 0.6 |
spec.normalize | string | no | target | Target normalization. Values: target, none. | normalize: none |
spec.variances | string | no | auto | Variance bars. Values: auto, none. | variances: none |
spec.level | string | no | auto | KPI row level. Values: auto, rowgroup, category, subcategory. | level: category |
spec.order | string | no | auto | Sort key of the KPI rows. Values: auto, rowgroup, rowgroupindex, category, categoryindex, subcategory, subcategoryindex, ac1–ac4, fc1–fc4, pp1–pp4, pl1–pl4. auto uses the dataset's suggested order. | order: ac1 |
spec.orderDirection | string | no | asc | Sorting direction. Values: asc, desc. Maps to the order-direction HTML attribute. | orderDirection: desc |
spec.limit | integer | no | 0 | Max KPI rows (truncates, no REST aggregate). 0 means unlimited. | limit: 6 |
spec.labels | object | no | show: auto, decimals: 1 | Value label configuration. | labels: { show: auto, decimals: 1 } |
spec.labels.show | string | no | auto | Toggles the value labels right of the bars. Values: auto, none. | show: none |
spec.labels.decimals | integer | no | 1 | Decimal places of the value labels, 0–4. | decimals: 0 |
spec.filter | string | no | "" | AlaSQL WHERE clause fragment to filter rows. | filter: "rowGroup = 'Revenue'" |
spec.chartTitle | string | no | "" | Custom chart title. Maps to the chart-title HTML attribute. | chartTitle: "KPI overview vs. plan" |
spec.scale | string or number | no | auto-scale with warning | Proportional scaling. "none": no scaling. "auto": auto-scale silently. A positive number such as 0.5 or 1.2: fixed factor. Omitted: auto-scales and warns with the applied factor. | scale: auto |
spec.i18nNamespace | string | no | — | I18n namespace for this component's labels; missing keys fall back to _system. Resolved at runtime from the nearest ancestor carrying one (card, page, tree, grid, or the artefact) when not set. Maps to the i18n-namespace HTML attribute. | i18nNamespace: audited |
spec.selectedStyle | string | no | — | Name of a ComponentStyle manifest to apply. Maps to the selected-style HTML attribute. | selectedStyle: corporate-style |
spec.ruleset | string | no | — | Name of a RuleSet manifest to apply, or inherited-closest / inherited-page. Maps to the ruleset HTML attribute. | ruleset: corporate-rules |
See ChartStructure for general bar charts
with explicit scenario and variance columns.