Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
docs: add JSDoc to transform functions and option types
Document ~24 exported functions and ~10 option types across 11
transform files: stack, dodge, window, shift, bollinger, jitter,
centroid, sort, select, recordize, and rename.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
  • Loading branch information
ljodea and claude committed Feb 11, 2026
commit b9155b51dbb878c9b169ea66048435550f7483ac
8 changes: 8 additions & 0 deletions src/lib/transforms/bollinger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,21 @@ export type BollingerOptions = {
k?: number;
};

/**
* computes Bollinger bands for the x channel, producing x1 (lower), x (mean),
* and x2 (upper) channels
*/
export function bollingerX<T>(
args: TransformArg<T>,
options: BollingerOptions = {}
): TransformArg<T> {
return bollingerDim('x', args, options);
}

/**
* computes Bollinger bands for the y channel, producing y1 (lower), y (mean),
* and y2 (upper) channels
*/
export function bollingerY<T>(
args: TransformArg<T>,
options: BollingerOptions = {}
Expand Down
4 changes: 4 additions & 0 deletions src/lib/transforms/centroid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ type WithCentroid<T> = T & {
[CENTROID]: [number, number];
};

/**
* computes the geographic centroid of each geometry feature, producing
* x (longitude) and y (latitude) channels
*/
export function geoCentroid<Datum extends DataRecord>({
data,
...options
Expand Down
11 changes: 11 additions & 0 deletions src/lib/transforms/dodge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,25 @@ import { groupFacetsAndZ } from 'svelteplot/helpers/group';
import type { ScaledDataRecord, TransformArg, PlotState } from 'svelteplot/types';

type BaseDodgeOptions = {
/** the anchor side for placing dodged marks */
anchor?: string;
/** the padding between dodged marks, in pixels */
padding?: number;
/** the radius of dodged marks, in pixels */
r?: number;
};

type AnchorX = 'left' | 'right' | 'middle';
type AnchorY = 'top' | 'bottom' | 'middle';

/** options for horizontal dodge positioning; can be an anchor string or a full options object */
export type DodgeXOptions =
| AnchorX
| (BaseDodgeOptions & {
anchor?: 'left' | 'right' | 'middle';
});

/** options for vertical dodge positioning; can be an anchor string or a full options object */
export type DodgeYOptions =
| AnchorY
| (BaseDodgeOptions & {
Expand All @@ -25,6 +30,9 @@ export type DodgeYOptions =

type AnchorFunction = (d: PlotState) => [number, number];

/**
* offsets marks horizontally to avoid overlap, using circle-packing
*/
export function dodgeX(
args: TransformArg<ScaledDataRecord>,
plotState: PlotState
Expand Down Expand Up @@ -52,6 +60,9 @@ export function dodgeX(
return dodge('x', 'y', anchorFunction, Number(padding), r, args, plotState);
}

/**
* offsets marks vertically to avoid overlap, using circle-packing
*/
export function dodgeY(
args: TransformArg<ScaledDataRecord>,
plotState: PlotState
Expand Down
9 changes: 9 additions & 0 deletions src/lib/transforms/jitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,25 @@ type JitterOptions = {
source?: () => number;
} & ({ type: 'uniform'; width?: number | string } | { type: 'normal'; std?: number | string });

/**
* adds random noise to the x channel values
*/
export function jitterX<T>(args: TransformArg<T>, options: JitterOptions): TransformReturn<T, 'x'> {
return jitter(args, { x: options });
}

/**
* adds random noise to the y channel values
*/
export function jitterY<T>(args: TransformArg<T>, options: JitterOptions): TransformReturn<T, 'y'> {
return jitter(args, { y: options });
}

type PositionalScale = 'x' | 'x1' | 'x2' | 'y' | 'y1' | 'y2';

/**
* adds random noise to one or more positional channels
*/
export function jitter<T, C extends TransformArg<T>>(
{ data, ...channels }: C,
options: Partial<Record<PositionalScale, JitterOptions>>
Expand Down
16 changes: 10 additions & 6 deletions src/lib/transforms/recordize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export function indexData<T extends object>(data: T[]): (T & { [INDEX]: number }
return data.map((d, i) => ({ ...d, [INDEX]: i }) as T & { [INDEX]: number });
}

/*
* This transform takes an array of raw values as input and returns data records
* in which the values are interpreted as x channel and their index as y
/**
* takes an array of raw values and returns data records in which the values
* are interpreted as the x channel and their index as the y channel
*/
export function recordizeX<T>(
{ data, ...channels }: TransformArgsRow<DataRow>,
Expand All @@ -38,9 +38,9 @@ export function recordizeX<T>(
return { data: indexData(data as object[]) as T[], ...channels };
}

/*
* This transform takes an array of raw values as input and returns data records
* in which the values are interpreted as y channel and their index as yx
/**
* takes an array of raw values and returns data records in which the values
* are interpreted as the y channel and their index as the x channel
*/
export function recordizeY<T>(
{ data, ...channels }: TransformArgsRow<DataRow>,
Expand Down Expand Up @@ -94,6 +94,10 @@ export function recordizeXY<T>({ data, ...channels }: TransformArgsRow<T>): Tran
return { data: data, ...channels };
}

/**
* wraps raw values into data records with index tracking, without
* assigning them to a specific positional channel
*/
export function recordize<T>({ data, ...channels }: TransformArgsRow<T>): TransformArgsRecord<T> {
if (!data) return { data, ...channels };
if (!isDataRecord(data[0])) {
Expand Down
4 changes: 4 additions & 0 deletions src/lib/transforms/rename.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ export function renameChannelsAndData<T>(
return renameChannels({ data: newData, ...channels }, options);
}

/**
* copies a channel's accessor to multiple target channels, then removes
* the source channel
*/
export function replaceChannels<T>(
{ data, ...channels }: TransformArg<T, DataRecord>,
options: ReplaceChannelsOptions
Expand Down
8 changes: 8 additions & 0 deletions src/lib/transforms/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ type SelectOptions =

// let o: SelectOptions = { x: 'min'};

/**
* selects one datum per group based on the given criteria; use "first"/"last"
* for positional selection, or {channel: "min"/"max"} for value-based selection
*/
export function select({ data, ...channels }: TransformArg<DataRecord>, options: SelectOptions) {
const newData: DataRecord[] = [];
groupFacetsAndZ(data, channels, (items) => {
Expand Down Expand Up @@ -53,15 +57,19 @@ export function selectLast(args: TransformArg<DataRecord>) {
return select(args, 'last');
}

/** keeps only the datum with the smallest x value per group */
export function selectMinX(args: TransformArg<DataRecord>) {
return select(args, { x: 'min' });
}
/** keeps only the datum with the largest x value per group */
export function selectMaxX(args: TransformArg<DataRecord>) {
return select(args, { x: 'max' });
}
/** keeps only the datum with the smallest y value per group */
export function selectMinY(args: TransformArg<DataRecord>) {
return select(args, { y: 'min' });
}
/** keeps only the datum with the largest y value per group */
export function selectMaxY(args: TransformArg<DataRecord>) {
return select(args, { y: 'max' });
}
8 changes: 8 additions & 0 deletions src/lib/transforms/shift.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyo
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
}[Keys];

/** per-channel shift amounts for x channels; values can be numbers or time interval strings (e.g. "1 month") */
type ShiftXOptions = {
[key in 'x' | 'x1' | 'x2']: string | number;
};

/**
* shifts the x channel values by a fixed amount or time interval
*/
export function shiftX(
{ data, ...channels }: TransformArg<DataRecord>,
shiftBy: string | number | RequireAtLeastOne<ShiftXOptions>
Expand All @@ -24,10 +28,14 @@ export function shiftX(
return { data, ...channels };
}

/** per-channel shift amounts for y channels; values can be numbers or time interval strings (e.g. "1 month") */
type ShiftYOptions = {
[key in 'y' | 'y1' | 'y2']: string | number;
};

/**
* shifts the y channel values by a fixed amount or time interval
*/
export function shiftY(
{ data, ...channels }: TransformArg<DataRecord>,
shiftBy: string | number | RequireAtLeastOne<ShiftYOptions>
Expand Down
4 changes: 4 additions & 0 deletions src/lib/transforms/sort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import { randomLcg } from 'd3-random';
export const SORT_KEY = Symbol('sortKey');
export const IS_SORTED = Symbol('isSorted');

/**
* sorts the data according to the sort channel option; supports channel
* accessors, comparator functions, and {channel, order} objects
*/
export function sort<T>(
{ data, ...channels }: TransformArg<T>,
options: { reverse?: boolean } = {}
Expand Down
20 changes: 20 additions & 0 deletions src/lib/transforms/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,19 @@ const DEFAULT_STACK_OPTIONS: StackOptions = {
reverse: false
};

/** the order in which series are stacked */
export type StackOrder = 'none' | 'appearance' | 'inside-out' | 'sum';
/** the offset method used to position stacked values */
export type StackOffset = 'none' | 'wiggle' | 'center' | 'normalize' | 'diverging';

/** options for the stack transform, or false to disable stacking */
export type StackOptions =
| {
/** the offset method, or null for the default (zero baseline) */
offset: null | StackOffset;
/** the stack order, or null for the default (input order) */
order: null | StackOrder;
/** if true, reverse the stack order */
reverse: boolean;
}
| false;
Expand Down Expand Up @@ -217,13 +223,19 @@ function stackXY<T>(
return { data, ...channels };
}

/**
* stacks data along the y dimension, producing y1 and y2 channels
*/
export function stackY<T>(
{ data, ...channels }: TransformArg<T>,
opts: Partial<StackOptions> = {}
): TransformArg<T> {
return stackXY('y', data, channels, applyDefaults(opts));
}

/**
* stacks data along the x dimension, producing x1 and x2 channels
*/
export function stackX<T>(
{ data, ...channels }: TransformArg<T>,
opts: Partial<StackOptions> = {}
Expand Down Expand Up @@ -340,10 +352,18 @@ function stackMosaic<T>(
};
}

/**
* creates a mosaic layout with the outer (width) dimension along x and
* the inner (height) dimension along y
*/
export function stackMosaicX<T>(args, opts) {
return stackMosaic(args, { outer: 'x', inner: 'y' }, opts);
}

/**
* creates a mosaic layout with the outer (height) dimension along y and
* the inner (width) dimension along x
*/
export function stackMosaicY<T>(args, opts) {
return stackMosaic(args, { outer: 'y', inner: 'x' }, opts);
}
12 changes: 12 additions & 0 deletions src/lib/transforms/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,28 @@ import type { DataRecord, ScaledChannelName, TransformArg } from '../types/index
import { groups as d3Groups } from 'd3-array';

type WindowOptions = {
/** the window size (number of data points) */
k: number;
/** a time interval string to use instead of a fixed window size */
interval: string;
/** where to align the window relative to the current data point */
anchor: 'start' | 'middle' | 'end';
/** the reducer function to apply within each window (e.g. "mean", "median", "sum") */
reduce: ReducerName;
/** if true, return null when the window has fewer than k values */
strict: boolean;
};

/**
* applies a sliding window reducer to the x channel
*/
export function windowX(args: TransformArg<DataRecord>, options: WindowOptions) {
return windowDim('x', args, options);
}

/**
* applies a sliding window reducer to the y channel
*/
export function windowY(args: TransformArg<DataRecord>, options: WindowOptions) {
return windowDim('y', args, options);
}
Expand Down