Files
buzz-sheet/lib/guides/export-image.ts
T
gunshiz fbc4d9d4b2
CI / Verify (push) Successful in 1m2s
CI / Build immutable images and deploy (push) Successful in 1m48s
feat(constellations) : add infographic image export
2026-09-03 15:07:22 +07:00

43 lines
1.3 KiB
TypeScript

export function imageContentDisposition(displayName: string, fallbackName: string): string {
const safeDisplayName = displayName.trim() || fallbackName;
const fallback = safeDisplayName
.normalize("NFKD")
.replace(/[^a-z0-9]+/giu, "-")
.replace(/^-|-$/gu, "") || fallbackName;
const encoded = encodeURIComponent(`${safeDisplayName}.png`).replace(
/['()*]/gu,
(character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`,
);
return `attachment; filename="${fallback}.png"; filename*=UTF-8''${encoded}`;
}
export interface ConstellationChartRow {
level: number;
percent: number;
isGreat: boolean;
widthPercent: number;
}
export function constellationChartRows(
rows: ReadonlyArray<{
level: number;
cumulativePercent: string;
isGreat: boolean;
}>,
): ConstellationChartRow[] {
const values = [
...rows.map((row) => ({
level: row.level,
percent: Number(row.cumulativePercent),
isGreat: row.isGreat,
})),
{ level: 0, percent: 100, isGreat: false },
].sort((left, right) => right.level - left.level);
const maximum = Math.max(100, ...values.map((row) => row.percent));
return values.map((row) => ({
...row,
widthPercent: Math.max(0, Math.min(100, (row.percent / maximum) * 100)),
}));
}