Chart families

Radial Bar charts

Compare category progress, targets, and signed baselines on independent tracks.

Radial Bar compares independent category values on concentric tracks. Each category owns one ring, and its absolute value maps to an angular sweep inside an explicit numeric domain.

This is intentionally different from the other radial families:

  • Pie and Donut divide one total into angular shares.
  • Concentric Donut compares several independent part-to-whole distributions.
  • Polar Column places categories around the angle and maps values to radius.
  • Radial Bar places categories on radius and maps values to angle.
  • Gauge charts present one or a small number of indicators, usually with zones and a dedicated gauge axis.

Radial Bar never derives a denominator from the supplied values.

Basic progress tracks

BravenChartPlus(
  series: [
    RadialBarChartSeries.fromMap(
      id: 'journey',
      name: 'Customer journey',
      unit: '%',
      values: const {
        'Activation': 92,
        'Retention': 78,
        'Adoption': 66,
        'Expansion': 57,
      },
      minimum: 0,
      maximum: 100,
      baseline: 0,
    ),
  ],
  radialBarChartConfig: const RadialBarChartConfig(
    thresholds: [
      RadialBarThreshold(value: 75, label: 'Target'),
    ],
  ),
)

Category identity follows map insertion order. The factory converts categories to stable zero-based point ordinals, so controller references, selection, tables, artifacts, hydration, and generated Dart source preserve the same identity.

Signed values

Set a domain that crosses zero and keep baseline: 0:

RadialBarChartSeries.fromMap(
  id: 'drivers',
  values: const {
    'Acquisition': 64,
    'Support': -36,
    'Reliability': 82,
    'Churn': -52,
  },
  minimum: -100,
  maximum: 100,
  baseline: 0,
)

Positive and negative marks sweep in opposite directions from the same baseline. Baseline, minimum, maximum, values, and thresholds are absolute values; none are normalized to shares.

Partial panes and track geometry

RadialBarChartConfig.pane uses the shared PolarPaneConfig:

const RadialBarChartConfig(
  pane: PolarPaneConfig(
    startAngleDegrees: -135,
    sweepAngleDegrees: 270,
    clockwise: true,
    innerRadiusFactor: 0.24,
    outerRadiusFactor: 0.84,
  ),
  trackGap: 8,
  trackOrder: RadialBarTrackOrder.outerToInner,
)

The renderer reduces a requested physical gap when a compact pane must fit many tracks. It never silently drops a category. Rounded ends are bounded by the resolved track thickness.

Marks, tracks, and gradients

RadialBarStyle controls mark and track treatment:

const RadialBarStyle(
  cornerRadius: 8,
  opacity: 1,
  borderWidth: 1,
  trackOpacity: 0.12,
  gradient: RadialBarGradientStyle(
    type: RadialBarGradientType.sweep,
    startLightnessShift: 0.16,
    endLightnessShift: -0.12,
  ),
  showDataLabels: true,
)

Leave colors null to inherit theme- and category-derived colors. Use barColors on RadialBarChartSeries.fromMap for category-specific mark colors. A gradient can derive both endpoints from each category color or use fixed startColor and endColor values. Sweep gradients follow the value arc; radial gradients shade across its thickness.

Value labels and category labels

Value labels are series styling because they describe individual marks:

const RadialBarStyle(
  showDataLabels: true,
  dataLabels: RadialBarDataLabelConfig(
    position: RadialBarDataLabelPosition.outsideCallout,
    content: RadialBarDataLabelContent.categoryAndValue,
    colorMode: RadialBarDataLabelColorMode.fixed,
    textStyle: PolarLabelStyle(
      color: Color(0xFF172033),
      fontSize: 12,
      fontWeight: FontWeight.w600,
    ),
    offset: 8,
    showPanel: true,
    connectorLength: 18,
    connectorWidth: 1,
  ),
)

insideEnd keeps each value on its mark and supports automatic contrast against the resolved mark paint. outsideCallout places values in collision-resolved side lanes. Fixed color is useful when a label or its panel must follow a product theme rather than the mark underneath it.

Category labels belong to RadialBarChartConfig because they describe the track layout:

const RadialBarChartConfig(
  showCategoryLabels: true,
  categoryLabels: RadialBarCategoryLabelConfig(
    position: RadialBarCategoryLabelPosition.startGap,
    orientation: RadialBarCategoryLabelOrientation.followStartAngle,
    offset: 8,
    textStyle: PolarLabelStyle(
      color: Color(0xFF172033),
      fontSize: 12,
    ),
  ),
)

startGap follows the configurable pane start angle while keeping text upright. outsideCallout uses category-colored connectors and thins labels deterministically when the available lane cannot fit every category. legacyOnTrack is retained for compatibility but is less resilient when text can cross both a dark mark and a light background.

Panels, offsets, connector length, width, and color are independently configurable for category and value labels. Under tight constraints or large text scale, visible labels may be thinned rather than overlapped or clipped; the underlying categories remain present in tables, export, focus traversal, and accessibility semantics.

Guides and thresholds

Category labels, scale labels, grid guides, tick count, and absolute threshold guides are configured on RadialBarChartConfig. Threshold values use the same explicit domain as the marks:

const RadialBarChartConfig(
  showScaleLabels: true,
  showGridLines: true,
  tickCount: 5,
  thresholds: [
    RadialBarThreshold(
      value: 75,
      label: 'Target',
      color: Color(0xFF0EA5E9),
      width: 1.5,
      dashPattern: [6, 4],
    ),
  ],
)

Selection, tooltips, and legends

RadialSelectionStyle selects either the shared explode treatment or a towards-viewer lift. Lift scale, offset, and backdrop blur are bounded so invalid transforms cannot enter the renderer:

selectionStyle: const RadialSelectionStyle(
  effect: RadialSelectionEffect.lift,
  liftScale: 1.08,
  liftOffset: 6,
  backdropBlur: 1.25,
),

Hover and keyboard focus resolve the exact annular mark, including a complete 100% arc. Tooltips use the shared tracking configuration and theme, so their visibility, text, panel, border, and opacity remain consistent with other chart families.

When showLegend is enabled on BravenChartPlus, one native legend item is generated per category track rather than one item for the whole series. ChartThemeData.legendStyle controls position, orientation, marker shape and size, text style, opacity, and panel treatment. Activating an item selects the same category in the chart and data table. Applications may also supply the shared radial legend item builder for richer value-card content; this does not create a Radial-Bar-specific legend system.

Interaction and developer tools

Radial Bar uses the shared hit, selection, focus, keyboard, tooltip, semantics, artifact, source, and Workbench contracts. Pointer input resolves the exact annular mark under the pointer. Keyboard traversal follows visible track order, Enter or Space selects, and Escape clears focus and selection. A baseline-valued category has no painted sweep but still remains accessible and exportable.

The native Workbench exposes Chart, Data, Split, and Source modes. Its table contains category, series, and absolute value columns; copy and CSV use the same rows. Chart documents preserve the explicit domain, baseline, style, selection style, pane, labels, grid, and thresholds.

The current contract accepts exactly one RadialBarChartSeries. Grouped or stacked tracks are deferred until their scale, table, selection, and composition semantics are specified rather than inferred from visual similarity.

The public Gallery at ?page=gallery includes three compact, independently runnable Radial Bar compositions:

  • Customer journey progress on an explicit 0-100 scale, with a target and outside value callouts.
  • Signed growth drivers around a shared zero baseline in a partial pane.
  • A dense regional operating profile that exercises rotated starts and collision-aware category callouts.

Use these cards to compare the family with the other chart types. Open the dedicated ?page=radial-bar showcase for the complete preset matrix, searchable property inspector, randomizer, Chart/Data/Split/Source Workbench, themes, legends, labels, gradients, selection, tooltips, and motion controls.