Skip to content
GitHub

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.

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).

The actual and target mappings accept either a bare scenario slot or an object whose measure property is a slot:

  • Scenario slots: ac1ac4, pp1pp4, fc1fc4, pl1pl4 — 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.

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).

  • level picks the hierarchy column that identifies a KPI row (auto uses the deepest populated level of rowGroupcategorysubCategory).
  • 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: none draws 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 operation column: "-" marks cost-type KPIs and inverts the sentiment (an actual below a cost target is favorable).
  • dataset – required dataset name, inline definition, or an array of those.
  • actual, target – optional measure mappings (slot or object with measure, 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 while normalize is target.
  • normalizetarget (default) or none.
  • variancesauto (default; variance bars in normalized mode) or none.
  • level – KPI row level.
  • order, orderDirection – row sorting; the sort key is auto, a hierarchy column (rowgroup, category, subcategory, or their …index variants) 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). 0 means unlimited.
  • labels – value labels: show (auto or none) and decimals (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 a ComponentStyle to apply; merged over the _system and _default styles.
  • ruleset – optional name of a RuleSet to apply, or inherited-closest / inherited-page to 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).

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: kpis
---
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: desc

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: 0
AttributeTypeRequiredDefaultDescription
apiVersionstringyesMust be bino.bi/v1alpha1.
kindstringyesMust be ChartBullet.
metadata.namestringyesUnique identifier.
metadata.labelsobjectnoKey-value pairs for categorization and constraint matching.
metadata.annotationsobjectnoArbitrary key-value metadata, not used by the system.
metadata.descriptionstringnoFree-form description.
metadata.constraintsarraynoConditional inclusion rules. See Constraints.
AttributeTypeRequiredDefaultDescriptionSample
spec.datasetstring, object, or arrayyesDataset reference: a name, an inline DataSet definition, or an array of those (at least one). Maps to the datasets HTML attribute.dataset: kpis
spec.actualstring or objectnoauto (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.measurestringyes (in object form)Plain scenario slot: ac1ac4, pp1pp4, fc1fc4, pl1pl4. Variance tokens are not allowed.measure: ac1
spec.actual.labelstringnoCaption of the measure, shown above the first row.label: "AC"
spec.actual.unitstringnoUnit 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.targetstring or objectnoauto (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.measurestringyes (in object form)Plain scenario slot: ac1ac4, pp1pp4, fc1fc4, pl1pl4. Variance tokens are not allowed.measure: pl1
spec.target.labelstringnoCaption of the measure, shown at the target line.label: "Plan"
spec.target.unitstringnoUnit caption, rendered once as in EUR k in the chart header.unit: "EUR k"
spec.rangesarray of numbersnoOne 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[]numberA single band boundary as a fraction of the target, greater than 0.0.6
spec.normalizestringnotargetTarget normalization. Values: target, none.normalize: none
spec.variancesstringnoautoVariance bars. Values: auto, none.variances: none
spec.levelstringnoautoKPI row level. Values: auto, rowgroup, category, subcategory.level: category
spec.orderstringnoautoSort key of the KPI rows. Values: auto, rowgroup, rowgroupindex, category, categoryindex, subcategory, subcategoryindex, ac1ac4, fc1fc4, pp1pp4, pl1pl4. auto uses the dataset's suggested order.order: ac1
spec.orderDirectionstringnoascSorting direction. Values: asc, desc. Maps to the order-direction HTML attribute.orderDirection: desc
spec.limitintegerno0Max KPI rows (truncates, no REST aggregate). 0 means unlimited.limit: 6
spec.labelsobjectnoshow: auto, decimals: 1Value label configuration.labels: { show: auto, decimals: 1 }
spec.labels.showstringnoautoToggles the value labels right of the bars. Values: auto, none.show: none
spec.labels.decimalsintegerno1Decimal places of the value labels, 04.decimals: 0
spec.filterstringno""AlaSQL WHERE clause fragment to filter rows.filter: "rowGroup = 'Revenue'"
spec.chartTitlestringno""Custom chart title. Maps to the chart-title HTML attribute.chartTitle: "KPI overview vs. plan"
spec.scalestring or numbernoauto-scale with warningProportional 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.i18nNamespacestringnoI18n 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.selectedStylestringnoName of a ComponentStyle manifest to apply. Maps to the selected-style HTML attribute.selectedStyle: corporate-style
spec.rulesetstringnoName 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.