@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.
80 lines (79 loc) • 2.52 kB
JavaScript
function toArray(source) {
return Array.isArray(source) ? source : Array.from(source);
}
function transformValues(data, value) {
if (typeof value === "function") {
const accessor = value;
return data.map((datum, index) => accessor(datum, { index, data }));
}
return data.map(
(datum) => datum != null && typeof datum === "object" ? datum[value] : void 0
);
}
function transformKey(value) {
if (Array.isArray(value)) {
return `tuple:${JSON.stringify(value.map((entry) => transformKey(entry)))}`;
}
if (value instanceof Date) return `date:${value.getTime()}`;
return `${typeof value}:${String(value)}`;
}
function groupedIndexes(keys) {
const groups = /* @__PURE__ */ new Map();
keys.forEach((key, index) => {
const identity = transformKey(key);
const group = groups.get(identity);
if (group) group.indexes.push(index);
else groups.set(identity, { key, indexes: [index] });
});
return [...groups.values()];
}
function materializeGroups(data, by) {
if (by === void 0) {
return [
{
group: {},
indexes: data.map((_, index) => index)
}
];
}
const entries = typeof by === "string" ? [[by, by]] : Object.entries(by);
const values = entries.map(([name, value]) => ({
name,
values: transformValues(data, value)
}));
const groups = /* @__PURE__ */ new Map();
data.forEach((_, index) => {
const group = Object.fromEntries(
values.map(({ name, values: fieldValues }) => [name, fieldValues[index]])
);
const identity = transformKey(Object.values(group));
const existing = groups.get(identity);
if (existing) existing.indexes.push(index);
else groups.set(identity, { group, indexes: [index] });
});
return [...groups.values()];
}
function orderedIndexes(data, indexes, orderBy, order = "ascending") {
if (orderBy === void 0) return [...indexes];
const values = transformValues(data, orderBy);
const direction = order === "descending" ? -1 : 1;
return [...indexes].sort((left, right) => {
const a = values[left];
const b = values[right];
const compared = compareChartValues(a, b);
return compared === 0 ? left - right : compared * direction;
});
}
function compareChartValues(left, right) {
const a = left instanceof Date ? left.getTime() : left;
const b = right instanceof Date ? right.getTime() : right;
return a < b ? -1 : a > b ? 1 : 0;
}
export {
groupedIndexes,
materializeGroups,
orderedIndexes,
toArray,
transformKey,
transformValues
};