OrbChartsOrbCharts

RacingPlot

RacingPlot is the core Plugin for the grid data format. It treats the category in the data as "animation frames" and series as the items in the race, playing frame by frame in category order to render an animated bar chart race where item rankings change over time.

Data format: grid

Supported charts

  • Racing ChartRacingBar, ValueLabel, SeriesLabel, CounterText, ValueAxis Layers

Quick start

A minimal configuration plays a bar chart race. RacingPlot shows all Layers by default: RacingBar, ValueLabel, SeriesLabel, CounterText, and ValueAxis:

import { OrbCharts } from '@orbcharts/core'
import type { RawData } from '@orbcharts/core'
import { RacingPlot, Tooltip, Legend } from '@orbcharts/plugin-basic'
 
const data: RawData = [
  { series: 'A', category: '2000', value: 30 },
  { series: 'A', category: '2001', value: 55 },
  { series: 'B', category: '2000', value: 20 },
  { series: 'B', category: '2001', value: 60 },
]
 
const chart = new OrbCharts(document.querySelector('#chart')!, {
  data,
  plugins: [
    new RacingPlot({ autorun: true, loop: true, frameInterval: 300 }),
    new Tooltip(),
    new Legend(),
  ],
})
 
// chart.destroy()

Tip: The chart fills its container by default, so set a width and height on the #chart container. See Core Concepts.

Each record in this grid data has series, category, and value: unlike a regular bar chart, RacingPlot treats category as a "frame", and the chart plays through them in category order (e.g. 2000, 2001). Each frame re-ranks and redraws the bars by each series's value, and CounterText is typically used to show the current frame (category).

How layer visibility works

RacingPlot is composed of multiple Layers, and the Layer names you list in the params are the Layers that get shown. If you specify no Layers (new RacingPlot()), it shows all 5 Layers by default: RacingBar, ValueLabel, SeriesLabel, CounterText, ValueAxis. You can also switch Layers dynamically with show/hide/showOnly after creation.

Tip: Layer visibility and the show/hide/showOnly/toggle methods are common to all Plugins. See Plugin API for the full explanation.

Chart examples

Racing Chart

new RacingPlot({ autorun: true, loop: true, frameInterval: 300 })

The three Plugin parameters autorun, loop, and frameInterval control playback: autorun decides whether playback starts automatically after loading, loop decides whether to loop after reaching the last frame, and frameInterval is the number of milliseconds each frame stays. The example above starts playing automatically on load and loops at 300 ms per frame.

Tip: Pair it with Legend and Tooltip for interactivity—added the same way as in GridPlot.

Plugin parameters

These parameters affect the whole RacingPlot's behavior, listed alongside Layer names in the same params object:

ParameterTypeDefaultDescription
rankedScale{ limit: number | 'auto' }{ limit: 10 }Ranking axis settings: limit is the max number of ranks shown ('auto' for automatic)
autorunbooleantrueWhether playback starts automatically after loading
loopbooleanfalseWhether to loop after reaching the last frame
frameIntervalnumber1000Number of milliseconds each frame stays
datasetIndexnumber0Which dataset to use when data is multi-dataset
stylesGraphicStylespadding is { 60, 60, 60, 60 }Shared visual styles (see Plugin API)
visibleFilter(datum) => boolean | null() => trueFilter which data to show (see Plugin API)

Note: styles and visibleFilter are shared by all chart Plugins; their structure and usage are documented centrally in Plugin API. Only RacingPlot's default differences are noted here (styles.padding defaults to { top: 60, right: 60, bottom: 60, left: 60 }, transitionDuration defaults to 500, and transitionEase defaults to 'easeLinear' for smooth frame-by-frame animation).

Layer parameters

Each Layer has its own parameters. The main parameters and defaults of each Layer are listed below.

About ColorType: color-related parameters use ColorType ('data', 'primary', etc.), mapping to the colors defined in the Theme. See Theme for the full explanation.

RacingBar

ParameterTypeDefaultDescription
barWidthnumber | nullnullBar width (px); null means auto-calculated
barPaddingnumber4Spacing between bars
barRadiusnumber | boolean4Corner radius; false for none, or a number for the radius

ValueLabel

ParameterTypeDefaultDescription
paddingnumber8Spacing between the label and the bar end
colorTypeColorType'primary'Label text color
valueFormatstring | ((text) => string)text => textValue text formatter

SeriesLabel

ParameterTypeDefaultDescription
labelstring''Axis label
labelOffset[number, number][0, 0]Axis label offset
labelColorTypeColorType'primary'Axis label color
seriesLabelPosition'inside-left' | 'inside-right' | 'outside''inside-right'Series label position
seriesLabelPaddingnumber20Series label padding
seriesLabelColorTypeColorType'dataContrast'Series label text color

CounterText

Typically used to show the current frame (category, e.g. a year).

ParameterTypeDefaultDescription
renderFn(categoryLabel, frameIndex, data) => string | string[](categoryLabel, frameIndex, data) => categoryLabelFunction computing the text to show for each frame
textAttrsArray<{ [key]: string | number }>[{}]SVG attributes of the text element
textStylesArray<{ [key]: string | number }>[{ 'font-size': '3em', 'font-weight': 'bold' }]CSS styles of the text element
paddingRightnumber0Spacing from the right edge
paddingBottomnumber0Spacing from the bottom edge

ValueAxis

ParameterTypeDefaultDescription
labelOffset[number, number][0, 0]Axis label offset
labelColorTypeColorType'primary'Axis label color
axisLineVisiblebooleantrueWhether to show the axis line
axisLineColorTypeColorType'primary'Axis line color
ticksnumber | nullnullNumber of ticks (null for auto)
tickFormatstring | ((text) => string)text => textTick text formatter
tickLineVisiblebooleantrueWhether to show tick lines
tickPaddingnumber20Spacing between tick and text
tickFullLinebooleantrueWhether to draw full gridlines
tickColorTypeColorType'secondary'Tick line color
tickTextColorTypeColorType'primary'Tick text color
placement'top' | 'bottom''top'Value axis placement

Full TypeScript interface

interface RacingPlotPluginParams {
  styles: GraphicStyles
  visibleFilter: (datum: ModelDatumGrid) => boolean | null
  datasetIndex: number
  rankedScale: {
    limit: number | 'auto'
  }
  autorun: boolean
  loop: boolean
  frameInterval: number
}
 
interface RacingPlotAllLayerParams {
  RacingBar: RacingPlotRacingBarParams
  ValueLabel: RacingPlotValueLabelParams
  SeriesLabel: RacingPlotSeriesLabelParams
  CounterText: RacingPlotCounterTextParams
  ValueAxis: RacingPlotValueAxisParams
}
 
// The constructor accepts a DeepPartial of both (Layer names alongside Plugin params)
new RacingPlot(params?: DeepPartial<RacingPlotPluginParams & RacingPlotAllLayerParams>)