feat(constellations) : add infographic image export
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { imageContentDisposition } from "@/lib/guides/export-image";
|
||||
import {
|
||||
constellationChartRows,
|
||||
imageContentDisposition,
|
||||
} from "@/lib/guides/export-image";
|
||||
|
||||
describe("guide image downloads", () => {
|
||||
it("provides a safe ASCII fallback and a UTF-8 filename", () => {
|
||||
@@ -14,4 +17,33 @@ describe("guide image downloads", () => {
|
||||
'filename="Arlecchino-R5.png"',
|
||||
);
|
||||
});
|
||||
|
||||
it("orders constellation levels, adds C0, and scales against the maximum", () => {
|
||||
const rows = constellationChartRows([
|
||||
{ level: 1, cumulativePercent: "117", isGreat: false },
|
||||
{ level: 6, cumulativePercent: "234", isGreat: true },
|
||||
]);
|
||||
|
||||
expect(rows.slice(0, 2)).toEqual([
|
||||
{ level: 6, percent: 234, isGreat: true, widthPercent: 100 },
|
||||
{ level: 1, percent: 117, isGreat: false, widthPercent: 50 },
|
||||
]);
|
||||
expect(rows[2]).toMatchObject({
|
||||
level: 0,
|
||||
percent: 100,
|
||||
isGreat: false,
|
||||
});
|
||||
expect(rows[2].widthPercent).toBeCloseTo(100 / 2.34);
|
||||
});
|
||||
|
||||
it("uses 100% as the minimum constellation chart scale", () => {
|
||||
expect(
|
||||
constellationChartRows([
|
||||
{ level: 2, cumulativePercent: "80", isGreat: false },
|
||||
]),
|
||||
).toEqual([
|
||||
{ level: 2, percent: 80, isGreat: false, widthPercent: 80 },
|
||||
{ level: 0, percent: 100, isGreat: false, widthPercent: 100 },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,3 +10,33 @@ export function imageContentDisposition(displayName: string, fallbackName: strin
|
||||
);
|
||||
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)),
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user