Geometric Series Builder

Visualizes the geometric series a + a·r + a·r² + a·r³ + ... as a vertical row of horizontal bars, one per term. Each bar's width is proportional to the term's magnitude, so a series with absolute ratio below 1 shows bars shrinking toward zero while the partial sum approaches the limit. Diverging series make the same visualization show why the sum never settles. The component is the foundation primitive for series convergence, recurrence-relation work, and Master-Theorem-style Big-O analysis.

Geometric series with a = 1 and r = 0.5. Showing 6 of 12 terms. Running sum is 1.969, limit 2.
a + a·r + a·r² + …term 06 / 12 · converges
1
0.5
0.25
0.125
0.0625
0.03125
a = 1r = 0.5Sₙ = 1.969S = 2
Customize
Series
1.00
0.50
6
Display

Installation

npx shadcn@latest add https://craftbits.dev/r/geometric-series-builder.json

Usage

import { GeometricSeriesBuilder } from "@craft-bits/core";
 
<GeometricSeriesBuilder a={1} r={0.5} defaultPlaying />

Drive the term count from outside the component:

const [n, setN] = useState(1);
 
<GeometricSeriesBuilder
  a={1}
  r={0.5}
  n={n}
  onNChange={setN}
/>

Show a divergent series (no limit line):

<GeometricSeriesBuilder a={1} r={1.4} maxN={8} />

Understanding the component

  1. One bar per term. Bar k has width proportional to the magnitude of the k-th term. The scale is fixed across the first maxN terms, so bars only ever shrink (or grow) into the same axis — they never re-scale around the user mid-build.
  2. Running sum, animated. The closed-form partial sum is rendered as a separate readout. Whenever the term count, first term, or ratio changes, the sum springs to its new value via SPRINGS.snap.
  3. Limit line, only when it makes sense. When the absolute ratio is below 1 and showLimit is on, a dotted vertical reference line is drawn at the convergence limit. For divergent series the line is suppressed and the header reads "diverges" instead of "converges".
  4. Negative ratios flip color. When a term is negative, its bar takes the cb-error border and label color. The width still uses magnitude so the bar remains visible.
  5. Autoplay uses setInterval. Each tick adds one term until the count hits maxN, then autoplay disables itself. The effect cleans up on unmount, pause, or term-count change — no orphaned timers.
  6. Controlled and uncontrolled twice over. n and playing each ship a value + onChange pair for controlled use and default* for uncontrolled.
  7. Reduced motion is honoured. With prefers-reduced-motion: reduce, every bar / sum spring collapses to instant, and the play button is disabled.

Props

PropTypeDefaultDescription
anumber1First term.
rnumber0.5Common ratio. Series converges when the absolute value is less than 1.
nnumberControlled visible-term count.
defaultNnumber6Uncontrolled initial visible-term count.
maxNnumber12Hard cap on autoplay growth and the scrubber range.
playingbooleanControlled play state.
defaultPlayingbooleanfalseUncontrolled initial play state.
playSpeednumber600Milliseconds between autoplay terms.
showLimitbooleantrueShow the dotted reference line at the convergence limit. No effect when the series diverges.
transitionTransitionSPRINGS.smoothSpring for the bar widths. The sum readout always uses SPRINGS.snap.
classNamestringMerged onto the root <div> via cn().

Accessibility

  • The whole figure is role="figure" with aria-labelledby pointing at the formula header.
  • An aria-live="polite" summary describes a, r, the visible-term count, the running sum, and the limit (or "diverges"). It re-announces whenever any of those change.
  • Step controls, the play / pause button, and the term-count scrubber each carry an explicit aria-label.
  • The play button uses aria-pressed so screen readers track the toggle state. It is disabled for users who prefer reduced motion.
  • Animation respects prefers-reduced-motion: reduce — every bar and sum transition collapses to instant, and autoplay is short-circuited.

Credits

  • Extracted from: algoflashcards (src/lessons/primitives/viz/GeometricSeriesBuilder.tsx). Generalized the lesson primitive into a math-viz teaching component: replaced the bespoke fractions-of-n API with a pure a + r parameterization, added controlled / uncontrolled state pairs for n and playing, added setInterval-driven autoplay with cleanup, replaced inline springs with SPRINGS.* tokens, replaced hex-suffix track fills with cb-accent-muted / cb-error token classes, and added an automatic limit-line whose visibility flips with the convergence criterion.