@tanstack/charts
Version:
A chart grammar for TypeScript and JavaScript. Marks consume your data directly, channels describe visual encodings, and the engine compiles them into a renderer-neutral keyed scene. TanStack's compact scales cover common numeric and categorical mappings.
67 lines (66 loc) • 1.89 kB
JavaScript
import {
materializeGroups,
orderedIndexes,
toArray
} from "./transform-internal.js";
import {
assertTransformOutputNames,
prepareOutputs,
reducePreparedOutputs
} from "./transform-reduce-internal.js";
function rollingWindow(source, options) {
const data = toArray(source);
const size = normalizeWindowSize(options.size);
assertTransformOutputNames(
options.outputs,
["source", "sourceIndexes"],
"rollingWindow"
);
const preparedOutputs = prepareOutputs(data, options.outputs);
return materializeGroups(data, options.by).flatMap(({ group, indexes }) => {
const ordered = orderedIndexes(
data,
indexes,
options.orderBy,
options.order
);
return ordered.flatMap((index, position) => {
const windowIndexes = selectedWindow(
ordered,
position,
size,
options.anchor ?? "end"
);
if (options.partial === false && windowIndexes.length < size) return [];
return [
{
...data[index],
source: windowIndexes.map(
(sourceIndex) => data[sourceIndex]
),
sourceIndexes: windowIndexes,
...reducePreparedOutputs(
data,
windowIndexes,
group,
preparedOutputs
)
}
];
});
});
}
function normalizeWindowSize(value) {
if (!Number.isFinite(value) || value <= 0) {
throw new TypeError("rollingWindow: size must be a positive finite number");
}
return Math.floor(value);
}
function selectedWindow(indexes, position, size, anchor) {
const start = anchor === "start" ? position : anchor === "middle" ? position - Math.floor((size - 1) / 2) : position - size + 1;
const end = anchor === "end" ? position + 1 : start + size;
return indexes.slice(Math.max(0, start), Math.min(indexes.length, end));
}
export {
rollingWindow
};