Documentation / @finchart/core / index / LttbDecimation
Class: LttbDecimation<T>
Defined in: packages/core/src/data/decimation.ts:424
Largest-Triangle-Three-Buckets. Picks a representative point by the area of the triangle formed by the previously chosen point, a candidate point, and the next bucket's average.
Preserves shape well, but one point per bucket means it can lose extremes. Use M4 when spikes matter. This one is for when you want a smooth trend line rendered in fewer points.
The triangle is measured on screen — since "visible shape" is this strategy's whole purpose, if the screen is a different space than x (bar index), area has to be measured in that space too.
Type Parameters
T
T extends BaseDataPoint = BaseDataPoint
Implements
Constructors
Constructor
new LttbDecimation<
T>(coordinates?):LttbDecimation<T>
Defined in: packages/core/src/data/decimation.ts:428
Defaults to the {x, y} accessor — same reason as M4Decimation's header comment.
Parameters
coordinates?
CoordinateAccessor<T> = ...
Returns
LttbDecimation<T>
Methods
decimate()
decimate(
data,range,threshold,screenXScan?,gapFree?):T[]
Defined in: packages/core/src/data/decimation.ts:432
Decimates only the [range.start, range.end) window, not all of data.
Why the window is a range, not an array: if the caller copied the visible range with slice, that's a big new array every frame on large data, most of it thrown away unused. Why the range is required, not optional: if it were optional, a strategy that doesn't know the range could decimate the whole array and the type system wouldn't catch it.
screenXScan is a factory that opens a pass for screen-place lookups (see Viewport.screenXScan). A strategy that buckets by x (M4Decimation, LttbDecimation) has to bucket in that same space when the screen space differs. Each sweep opens one pass — the cursor belongs to that pass, so strategies and frames can't interfere with each other. If absent, x is the screen place (continuous coordinate space, the default).
gapFree is a fact the caller already knows — if true, this data is guaranteed gap-free, so the window scan that would otherwise find gap boundaries is skipped. Gap presence is a property of the array, not the window, so the viewport cache can't save this for you — only the side that owns the changes can maintain it incrementally.
Not merged with gapless — that's a static fact about the accessor, this is runtime state of the array.
False covers "don't know," not just "has gaps" — the safe default is false. Passing true incorrectly swallows gaps, and the line runs straight across a spot that should have no value.
Parameters
data
T[]
range
threshold
number
screenXScan?
() => (x) => number
gapFree?
boolean
Returns
T[]